DragonFlyBSD Kernel Audit
DF-0522 / fix.diff
← back to finding ↓ download raw
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;