summaryrefslogtreecommitdiff
path: root/sys/kern/uipc_usrreq.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2012-04-14 09:42:33 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2012-04-14 09:42:33 +0000
commit0f552c123aac57c06419300338767d57fbabe9db (patch)
tree9851ee736da123b1d35e603178b208373d793815 /sys/kern/uipc_usrreq.c
parent576433f81918e999d238d312ba1c6e5b71d36280 (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.c13
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);
}