diff --git a/sys/netgraph/ksocket/ng_ksocket.c b/sys/netgraph/ksocket/ng_ksocket.c @@ -556,12 +556,21 @@ static int ng_ksocket_newhook(node_p node, hook_p hook, const char *name0) { - struct thread *td = curthread->td_proc ? curthread : &thread0; /* XXX broken */ + struct thread *td; const priv_p priv = node->private; struct ng_mesg *msg; char *s1, *s2, name[NG_HOOKSIZ]; int family, type, protocol, error; + /* Do NOT fall back to &thread0 (root credentials) when invoked from a + * kernel/netgraph dispatch context (curthread->td_proc == NULL). + * Doing so evaluates socket privilege checks (PRIV_NET_RAW, bind<1024, + * jail) against root, which is the documented "XXX broken" behaviour. + * Fail closed instead. */ + if (curthread->td_proc == NULL) + return (EACCES); + td = curthread; + /* Check if we're already connected */ if (priv->hook != NULL) return (EISCONN); @@ -637,7 +646,12 @@ ng_ksocket_rcvmsg(node_p node, struct ng_mesg *msg, const char *raddr, struct ng_mesg **rptr) { - struct thread *td = curthread->td_proc ? curthread : &thread0; /* XXX broken */ + struct thread *td; + + /* Fail closed: never fall back to thread0 (root) credentials. */ + if (curthread->td_proc == NULL) + return (EACCES); + td = curthread; const priv_p priv = node->private; struct socket *const so = priv->so; struct ng_mesg *resp = NULL; @@ -877,7 +891,12 @@ static int ng_ksocket_rcvdata(hook_p hook, struct mbuf *m, meta_p meta) { - struct thread *td = curthread->td_proc ? curthread : &thread0; /* XXX broken */ + struct thread *td; + + /* Fail closed: never fall back to thread0 (root) credentials. */ + if (curthread->td_proc == NULL) + return (EACCES); + td = curthread; const node_p node = hook->node; const priv_p priv = node->private; struct socket *const so = priv->so;