Changeset View
Changeset View
Standalone View
Standalone View
head/sys/kern/uipc_usrreq.c
Show First 20 Lines • Show All 2,114 Lines • ▼ Show 20 Lines | #endif | ||||
LIST_INIT(&unp_sphead); | LIST_INIT(&unp_sphead); | ||||
SLIST_INIT(&unp_defers); | SLIST_INIT(&unp_defers); | ||||
TIMEOUT_TASK_INIT(taskqueue_thread, &unp_gc_task, 0, unp_gc, NULL); | TIMEOUT_TASK_INIT(taskqueue_thread, &unp_gc_task, 0, unp_gc, NULL); | ||||
TASK_INIT(&unp_defer_task, 0, unp_process_defers, NULL); | TASK_INIT(&unp_defer_task, 0, unp_process_defers, NULL); | ||||
UNP_LINK_LOCK_INIT(); | UNP_LINK_LOCK_INIT(); | ||||
UNP_DEFERRED_LOCK_INIT(); | UNP_DEFERRED_LOCK_INIT(); | ||||
} | } | ||||
static void | |||||
unp_internalize_cleanup_rights(struct mbuf *control) | |||||
{ | |||||
struct cmsghdr *cp; | |||||
struct mbuf *m; | |||||
void *data; | |||||
socklen_t datalen; | |||||
for (m = control; m != NULL; m = m->m_next) { | |||||
cp = mtod(m, struct cmsghdr *); | |||||
if (cp->cmsg_level != SOL_SOCKET || | |||||
cp->cmsg_type != SCM_RIGHTS) | |||||
continue; | |||||
data = CMSG_DATA(cp); | |||||
datalen = (caddr_t)cp + cp->cmsg_len - (caddr_t)data; | |||||
unp_freerights(data, datalen / sizeof(struct filedesc *)); | |||||
} | |||||
} | |||||
static int | static int | ||||
unp_internalize(struct mbuf **controlp, struct thread *td) | unp_internalize(struct mbuf **controlp, struct thread *td) | ||||
{ | { | ||||
struct mbuf *control = *controlp; | struct mbuf *control, **initial_controlp; | ||||
struct proc *p = td->td_proc; | struct proc *p; | ||||
struct filedesc *fdesc = p->p_fd; | struct filedesc *fdesc; | ||||
struct bintime *bt; | struct bintime *bt; | ||||
struct cmsghdr *cm = mtod(control, struct cmsghdr *); | struct cmsghdr *cm; | ||||
struct cmsgcred *cmcred; | struct cmsgcred *cmcred; | ||||
struct filedescent *fde, **fdep, *fdev; | struct filedescent *fde, **fdep, *fdev; | ||||
struct file *fp; | struct file *fp; | ||||
struct timeval *tv; | struct timeval *tv; | ||||
struct timespec *ts; | struct timespec *ts; | ||||
int i, *fdp; | |||||
void *data; | void *data; | ||||
socklen_t clen = control->m_len, datalen; | socklen_t clen, datalen; | ||||
int error, oldfds; | int i, error, *fdp, oldfds; | ||||
u_int newlen; | u_int newlen; | ||||
UNP_LINK_UNLOCK_ASSERT(); | UNP_LINK_UNLOCK_ASSERT(); | ||||
p = td->td_proc; | |||||
fdesc = p->p_fd; | |||||
error = 0; | error = 0; | ||||
control = *controlp; | |||||
clen = control->m_len; | |||||
*controlp = NULL; | *controlp = NULL; | ||||
while (cm != NULL) { | initial_controlp = controlp; | ||||
for (cm = mtod(control, struct cmsghdr *); cm != NULL;) { | |||||
if (sizeof(*cm) > clen || cm->cmsg_level != SOL_SOCKET | if (sizeof(*cm) > clen || cm->cmsg_level != SOL_SOCKET | ||||
|| cm->cmsg_len > clen || cm->cmsg_len < sizeof(*cm)) { | || cm->cmsg_len > clen || cm->cmsg_len < sizeof(*cm)) { | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
data = CMSG_DATA(cm); | data = CMSG_DATA(cm); | ||||
datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; | datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; | ||||
▲ Show 20 Lines • Show All 134 Lines • ▼ Show 20 Lines | if (CMSG_SPACE(datalen) < clen) { | ||||
((caddr_t)cm + CMSG_SPACE(datalen)); | ((caddr_t)cm + CMSG_SPACE(datalen)); | ||||
} else { | } else { | ||||
clen = 0; | clen = 0; | ||||
cm = NULL; | cm = NULL; | ||||
} | } | ||||
} | } | ||||
out: | out: | ||||
if (error != 0 && initial_controlp != NULL) | |||||
unp_internalize_cleanup_rights(*initial_controlp); | |||||
m_freem(control); | m_freem(control); | ||||
return (error); | return (error); | ||||
} | } | ||||
static struct mbuf * | static struct mbuf * | ||||
unp_addsockcred(struct thread *td, struct mbuf *control) | unp_addsockcred(struct thread *td, struct mbuf *control) | ||||
{ | { | ||||
struct mbuf *m, *n, *n_prev; | struct mbuf *m, *n, *n_prev; | ||||
▲ Show 20 Lines • Show All 519 Lines • Show Last 20 Lines |