summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Beck <beck@cvs.openbsd.org>2005-08-04 16:12:33 +0000
committerBob Beck <beck@cvs.openbsd.org>2005-08-04 16:12:33 +0000
commit68f737d79dd3406bf093d5de9b04ad6e3b29f653 (patch)
tree32d966ee9cf1f82492b3fe4ac88c1eff533854ff
parent4b0919a67c6f29923af9613023ff142148317c6b (diff)
fix worst three kernel stack pigs in xfs by moving stack allocation of
xfs message structures to malloc M_TEMP. ok art@
-rw-r--r--sys/xfs/xfs_syscalls-common.c50
-rw-r--r--sys/xfs/xfs_vfsops-common.c27
-rw-r--r--sys/xfs/xfs_vnodeops-common.c28
3 files changed, 70 insertions, 35 deletions
diff --git a/sys/xfs/xfs_syscalls-common.c b/sys/xfs/xfs_syscalls-common.c
index fa85b6649e8..271ac225245 100644
--- a/sys/xfs/xfs_syscalls-common.c
+++ b/sys/xfs/xfs_syscalls-common.c
@@ -492,58 +492,68 @@ remote_pioctl (d_thread_t *p,
struct ViceIoctl *vice_ioctl,
struct vnode *vp)
{
- int error;
- struct xfs_message_pioctl msg;
+ int error = 0;
+ struct xfs_message_pioctl *msg = NULL;
struct xfs_message_wakeup_data *msg2;
+ msg = malloc(sizeof(struct xfs_message_symlink), M_TEMP, M_WAITOK);
+ if (msg == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
+ memset(msg, 0, sizeof(*msg));
+
if (vp != NULL) {
struct xfs_node *xn;
if (vp->v_tag != VT_AFS) {
NNPFSDEB(XDEBSYS, ("xfs_syscall: file is not in afs\n"));
vrele(vp);
- return EINVAL;
+ error = EINVAL;
+ goto done;
}
xn = VNODE_TO_XNODE(vp);
- msg.handle = xn->handle;
+ msg->handle = xn->handle;
vrele(vp);
}
if (vice_ioctl->in_size < 0) {
printf("xfs: remote pioctl: got a negative data size: opcode: %d",
SCARG(arg, a_opcode));
- return EINVAL;
+ error = EINVAL;
+ goto done;
}
if (vice_ioctl->in_size > NNPFS_MSG_MAX_DATASIZE) {
printf("xfs_pioctl_call: got a humongous in packet: opcode: %d",
SCARG(arg, a_opcode));
- return EINVAL;
+ error = EINVAL;
+ goto done;
}
if (vice_ioctl->in_size != 0) {
- error = copyin(vice_ioctl->in, msg.msg, vice_ioctl->in_size);
+ error = copyin(vice_ioctl->in, msg->msg, vice_ioctl->in_size);
if (error)
- return error;
+ goto done;
}
- msg.header.opcode = NNPFS_MSG_PIOCTL;
- msg.header.size = sizeof(msg);
- msg.opcode = SCARG(arg, a_opcode);
+ msg->header.opcode = NNPFS_MSG_PIOCTL;
+ msg->header.size = sizeof(*msg);
+ msg->opcode = SCARG(arg, a_opcode);
- msg.insize = vice_ioctl->in_size;
- msg.outsize = vice_ioctl->out_size;
+ msg->insize = vice_ioctl->in_size;
+ msg->outsize = vice_ioctl->out_size;
#ifdef HAVE_FREEBSD_THREAD
- msg.cred.uid = xfs_thread_to_euid(p);
- msg.cred.pag = xfs_get_pag(xfs_thread_to_cred(p));
+ msg->cred.uid = xfs_thread_to_euid(p);
+ msg->cred.pag = xfs_get_pag(xfs_thread_to_cred(p));
#else
- msg.cred.uid = xfs_proc_to_euid(p);
- msg.cred.pag = xfs_get_pag(xfs_proc_to_cred(p));
+ msg->cred.uid = xfs_proc_to_euid(p);
+ msg->cred.pag = xfs_get_pag(xfs_proc_to_cred(p));
#endif
- error = xfs_message_rpc(0, &msg.header, sizeof(msg), p); /* XXX */
- msg2 = (struct xfs_message_wakeup_data *) &msg;
+ error = xfs_message_rpc(0, &(msg->header), sizeof(*msg), p); /* XXX */
+ msg2 = (struct xfs_message_wakeup_data *) msg;
if (error == 0)
error = msg2->error;
@@ -563,6 +573,8 @@ remote_pioctl (d_thread_t *p,
error = copyout(msg2->msg, vice_ioctl->out, len);
}
+ done:
+ free(msg, M_TEMP);
return error;
}
diff --git a/sys/xfs/xfs_vfsops-common.c b/sys/xfs/xfs_vfsops-common.c
index 1b3a9bc49b3..60c1a669f7d 100644
--- a/sys/xfs/xfs_vfsops-common.c
+++ b/sys/xfs/xfs_vfsops-common.c
@@ -196,19 +196,34 @@ xfs_mount_common(struct mount *mp,
struct nameidata *ndp,
d_thread_t *p)
{
- char path[MAXPATHLEN];
- char data[MAXPATHLEN];
+ char *path = NULL;
+ char *data = NULL;
size_t count;
- int error;
+ int error = 0;
+
+ data = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
+ if (data == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
+ path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
+ if (path == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
error = copyinstr(user_path, path, MAXPATHLEN, &count);
if (error)
- return error;
+ goto done;
error = copyinstr(user_data, data, MAXPATHLEN, &count);
if (error)
- return error;
- return xfs_mount_common_sys (mp, path, data, ndp, p);
+ goto done;
+ error = xfs_mount_common_sys (mp, path, data, ndp, p);
+done:
+ free(data, M_TEMP);
+ free(path, M_TEMP);
+ return(error);
}
#ifdef HAVE_KERNEL_DOFORCE
diff --git a/sys/xfs/xfs_vnodeops-common.c b/sys/xfs/xfs_vnodeops-common.c
index 9cea2173aa6..0c223988671 100644
--- a/sys/xfs/xfs_vnodeops-common.c
+++ b/sys/xfs/xfs_vnodeops-common.c
@@ -925,30 +925,38 @@ xfs_symlink_common(struct vnode *dvp,
d_thread_t *proc = xfs_cnp_to_proc(cnp);
struct ucred *cred = xfs_proc_to_cred(proc);
#endif
- struct xfs_message_symlink msg;
+ struct xfs_message_symlink *msg = NULL;
const char *name = cnp->cn_nameptr;
int error = 0;
NNPFSDEB(XDEBVNOPS, ("xfs_symlink: %s\n", name));
- msg.header.opcode = NNPFS_MSG_SYMLINK;
- msg.parent_handle = xn->handle;
- vattr2xfs_attr(vap, &msg.attr);
- msg.cred.uid = cred->cr_uid;
- msg.cred.pag = xfs_get_pag(cred);
- if (strlcpy (msg.contents, target, sizeof(msg.contents)) >= NNPFS_MAX_SYMLINK_CONTENT) {
+ msg = malloc(sizeof(struct xfs_message_symlink), M_TEMP, M_WAITOK);
+ if (msg == NULL) {
+ error = ENOMEM;
+ goto done;
+ }
+ memset(msg, 0, sizeof(*msg));
+
+ msg->header.opcode = NNPFS_MSG_SYMLINK;
+ msg->parent_handle = xn->handle;
+ vattr2xfs_attr(vap, &msg->attr);
+ msg->cred.uid = cred->cr_uid;
+ msg->cred.pag = xfs_get_pag(cred);
+ if (strlcpy (msg->contents, target, sizeof(msg->contents)) >= NNPFS_MAX_SYMLINK_CONTENT) {
error = ENAMETOOLONG;
goto done;
}
- if (strlcpy(msg.name, name, sizeof(msg.name)) >= NNPFS_MAX_NAME) {
+ if (strlcpy(msg->name, name, sizeof(msg->name)) >= NNPFS_MAX_NAME) {
error = ENAMETOOLONG;
goto done;
}
- error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), proc);
+ error = xfs_message_rpc(xfsp->fd, &msg->header, sizeof(*msg), proc);
if (error == 0)
- error = ((struct xfs_message_wakeup *) & msg)->error;
+ error = ((struct xfs_message_wakeup *) msg)->error;
done:
+ free(msg, M_TEMP);
return error;
}