diff options
author | mjg <mjg@FreeBSD.org> | 2013-04-14 17:08:34 +0000 |
---|---|---|
committer | mjg <mjg@FreeBSD.org> | 2013-04-14 17:08:34 +0000 |
commit | 1798a915c42b5d2350b14301401678655b36dc60 (patch) | |
tree | 2db21f81359000be9aa1f9886e4e21bf05d233bf /sys/kern/uipc_usrreq.c | |
parent | 4faf1388732c8b3f6d69d6c4342df72795867b90 (diff) | |
download | FreeBSD-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.c | 21 |
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); |