summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_usrreq.c
diff options
context:
space:
mode:
authormjg <mjg@FreeBSD.org>2013-04-14 17:08:34 +0000
committermjg <mjg@FreeBSD.org>2013-04-14 17:08:34 +0000
commit1798a915c42b5d2350b14301401678655b36dc60 (patch)
tree2db21f81359000be9aa1f9886e4e21bf05d233bf /sys/kern/uipc_usrreq.c
parent4faf1388732c8b3f6d69d6c4342df72795867b90 (diff)
downloadFreeBSD-src-1798a915c42b5d2350b14301401678655b36dc60.zip
FreeBSD-src-1798a915c42b5d2350b14301401678655b36dc60.tar.gz
Add fdallocn function and use it when passing fds over unix socket.
This gets rid of "unp_externalize fdalloc failed" panic. Reviewed by: pjd MFC after: 1 week
Diffstat (limited to 'sys/kern/uipc_usrreq.c')
-rw-r--r--sys/kern/uipc_usrreq.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index 9b60eab..011c3ee 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1706,7 +1706,6 @@ unp_externalize(struct mbuf *control, struct mbuf **controlp, int flags)
void *data;
socklen_t clen = control->m_len, datalen;
int error, newfds;
- int f;
u_int newlen;
UNP_LINK_UNLOCK_ASSERT();
@@ -1732,13 +1731,6 @@ unp_externalize(struct mbuf *control, struct mbuf **controlp, int flags)
goto next;
}
FILEDESC_XLOCK(fdesc);
- /* if the new FD's will not fit free them. */
- if (!fdavail(td, newfds)) {
- FILEDESC_XUNLOCK(fdesc);
- error = EMSGSIZE;
- unp_freerights(fdep, newfds);
- goto next;
- }
/*
* Now change each pointer to an fd in the global
@@ -1758,17 +1750,22 @@ unp_externalize(struct mbuf *control, struct mbuf **controlp, int flags)
fdp = (int *)
CMSG_DATA(mtod(*controlp, struct cmsghdr *));
+ if (fdallocn(td, 0, fdp, newfds) != 0) {
+ FILEDESC_XUNLOCK(td->td_proc->p_fd);
+ error = EMSGSIZE;
+ unp_freerights(fdep, newfds);
+ m_freem(*controlp);
+ *controlp = NULL;
+ goto next;
+ }
for (i = 0; i < newfds; i++, fdp++) {
- if (fdalloc(td, 0, &f))
- panic("unp_externalize fdalloc failed");
- fde = &fdesc->fd_ofiles[f];
+ fde = &fdesc->fd_ofiles[*fdp];
fde->fde_file = fdep[0]->fde_file;
filecaps_move(&fdep[0]->fde_caps,
&fde->fde_caps);
if ((flags & MSG_CMSG_CLOEXEC) != 0)
fde->fde_flags |= UF_EXCLOSE;
unp_externalize_fp(fde->fde_file);
- *fdp = f;
}
FILEDESC_XUNLOCK(fdesc);
free(fdep[0], M_FILECAPS);
OpenPOWER on IntegriCloud