diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2012-04-14 09:42:33 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2012-04-14 09:42:33 +0000 |
commit | 0f552c123aac57c06419300338767d57fbabe9db (patch) | |
tree | 9851ee736da123b1d35e603178b208373d793815 /sys/kern/uipc_usrreq.c | |
parent | 576433f81918e999d238d312ba1c6e5b71d36280 (diff) |
Do not just return in case the provided control buffer is too short since
that leaks all the file pointers. Instead make sure that the exit path via
restart: -> out: does not free the uninitialized pointer.
OK deraadt@ guenther@
Diffstat (limited to 'sys/kern/uipc_usrreq.c')
-rw-r--r-- | sys/kern/uipc_usrreq.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index dbab77cd65e..94c38e4a098 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_usrreq.c,v 1.63 2012/04/14 09:07:42 claudio Exp $ */ +/* $OpenBSD: uipc_usrreq.c,v 1.64 2012/04/14 09:42:32 claudio Exp $ */ /* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */ /* @@ -631,7 +631,7 @@ unp_externalize(struct mbuf *rights, socklen_t controllen) { struct proc *p = curproc; /* XXX */ struct cmsghdr *cm = mtod(rights, struct cmsghdr *); - int i, *fdp; + int i, *fdp = NULL; struct file **rp; struct file *fp; int nfds, error = 0; @@ -642,8 +642,10 @@ unp_externalize(struct mbuf *rights, socklen_t controllen) controllen = 0; else controllen -= CMSG_ALIGN(sizeof(struct cmsghdr)); - if (nfds > controllen / sizeof(int)) - return (EMSGSIZE); + if (nfds > controllen / sizeof(int)) { + error = EMSGSIZE; + goto restart; + } rp = (struct file **)CMSG_DATA(cm); @@ -745,7 +747,8 @@ restart: rights->m_len = CMSG_LEN(nfds * sizeof(int)); out: fdpunlock(p->p_fd); - free(fdp, M_TEMP); + if (fdp) + free(fdp, M_TEMP); return (error); } |