Module Name:    src
Committed By:   ozaki-r
Date:           Tue Aug  8 10:41:33 UTC 2017

Modified Files:
        src/sys/netipsec: keysock.c

Log Message:
Fix KASSERT(solocked(sb->sb_so)) failure in sbappendaddr that is called 
eventually from key_sendup_mbuf

If key_sendup_mbuf isn't passed a socket, the assertion fails.
Originally in this case sb->sb_so was softnet_lock and callers
held softnet_lock so the assertion was magically satisfied.
Now sb->sb_so is key_so_mtx and also softnet_lock isn't always
held by callers so the assertion can fail.

Fix it by holding key_so_mtx if key_sendup_mbuf isn't passed a socket.

Reported by knakahara@
Tested by knakahara@ and ozaki-r@


To generate a diff of this commit:
cvs rdiff -u -r1.59 -r1.60 src/sys/netipsec/keysock.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netipsec/keysock.c
diff -u src/sys/netipsec/keysock.c:1.59 src/sys/netipsec/keysock.c:1.60
--- src/sys/netipsec/keysock.c:1.59	Thu Jul 27 09:53:57 2017
+++ src/sys/netipsec/keysock.c	Tue Aug  8 10:41:33 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: keysock.c,v 1.59 2017/07/27 09:53:57 ozaki-r Exp $	*/
+/*	$NetBSD: keysock.c,v 1.60 2017/08/08 10:41:33 ozaki-r Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/keysock.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.59 2017/07/27 09:53:57 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.60 2017/08/08 10:41:33 ozaki-r Exp $");
 
 /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */
 
@@ -300,8 +300,8 @@ key_sendup(struct socket *so, struct sad
 }
 
 /* so can be NULL if target != KEY_SENDUP_ONE */
-int
-key_sendup_mbuf(struct socket *so, struct mbuf *m,
+static int
+_key_sendup_mbuf(struct socket *so, struct mbuf *m,
 		int target/*, sbprio */)
 {
 	struct mbuf *n;
@@ -433,6 +433,24 @@ key_sendup_mbuf(struct socket *so, struc
 	return error;
 }
 
+int
+key_sendup_mbuf(struct socket *so, struct mbuf *m,
+		int target/*, sbprio */)
+{
+	int error;
+
+	if (so == NULL)
+		mutex_enter(key_so_mtx);
+	else
+		KASSERT(solocked(so));
+
+	error = _key_sendup_mbuf(so, m, target);
+
+	if (so == NULL)
+		mutex_exit(key_so_mtx);
+	return error;
+}
+
 static int
 key_attach(struct socket *so, int proto)
 {

Reply via email to