* Dispose of externalized rights from an SCM_RIGHTS message. This function * should be used in error or truncation cases to avoid leaking file descriptors * into the recipient's (the current thread's) table. */
| 1593 | * into the recipient's (the current thread's) table. |
| 1594 | */ |
| 1595 | void |
| 1596 | m_dispose_extcontrolm(struct mbuf *m) |
| 1597 | { |
| 1598 | struct cmsghdr *cm; |
| 1599 | struct file *fp; |
| 1600 | struct thread *td; |
| 1601 | socklen_t clen, datalen; |
| 1602 | int error, fd, *fds, nfd; |
| 1603 | |
| 1604 | td = curthread; |
| 1605 | for (; m != NULL; m = m->m_next) { |
| 1606 | if (m->m_type != MT_EXTCONTROL) |
| 1607 | continue; |
| 1608 | cm = mtod(m, struct cmsghdr *); |
| 1609 | clen = m->m_len; |
| 1610 | while (clen > 0) { |
| 1611 | if (clen < sizeof(*cm)) |
| 1612 | panic("%s: truncated mbuf %p", __func__, m); |
| 1613 | datalen = CMSG_SPACE(cm->cmsg_len - CMSG_SPACE(0)); |
| 1614 | if (clen < datalen) |
| 1615 | panic("%s: truncated mbuf %p", __func__, m); |
| 1616 | |
| 1617 | if (cm->cmsg_level == SOL_SOCKET && |
| 1618 | cm->cmsg_type == SCM_RIGHTS) { |
| 1619 | fds = (int *)CMSG_DATA(cm); |
| 1620 | nfd = (cm->cmsg_len - CMSG_SPACE(0)) / |
| 1621 | sizeof(int); |
| 1622 | |
| 1623 | while (nfd-- > 0) { |
| 1624 | fd = *fds++; |
| 1625 | error = fget(td, fd, &cap_no_rights, |
| 1626 | &fp); |
| 1627 | if (error == 0) { |
| 1628 | fdclose(td, fp, fd); |
| 1629 | fdrop(fp, td); |
| 1630 | } |
| 1631 | } |
| 1632 | } |
| 1633 | clen -= datalen; |
| 1634 | cm = (struct cmsghdr *)((uint8_t *)cm + datalen); |
| 1635 | } |
| 1636 | m_chtype(m, MT_CONTROL); |
| 1637 | } |
| 1638 | } |
no test coverage detected