diff options
author | Bob Beck <beck@cvs.openbsd.org> | 2005-08-04 16:12:33 +0000 |
---|---|---|
committer | Bob Beck <beck@cvs.openbsd.org> | 2005-08-04 16:12:33 +0000 |
commit | 68f737d79dd3406bf093d5de9b04ad6e3b29f653 (patch) | |
tree | 32d966ee9cf1f82492b3fe4ac88c1eff533854ff | |
parent | 4b0919a67c6f29923af9613023ff142148317c6b (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.c | 50 | ||||
-rw-r--r-- | sys/xfs/xfs_vfsops-common.c | 27 | ||||
-rw-r--r-- | sys/xfs/xfs_vnodeops-common.c | 28 |
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; } |