KKASSERTs in sys/kern/uipc_{msg,socket}.c are too strict

Rumko rumcic at gmail.com
Mon Dec 29 13:55:41 PST 2008


The code for nfs root mounts does not use kmalloc-ed space for some vars, while
some KKASSERTs in the mentioned files only check for the supplied pointers if
they were kmalloc-ed or not.
The attached patch adds a check if the supplied pointers are not in user stack
(if they are in kernel stack) ... since kmalloc-ed space also resides in the
addresses not in user stack, maybe kva_p should be removed (is it used
anywhere else?)?
-- 
Regards,
Rumko
diff --git a/sys/kern/uipc_msg.c b/sys/kern/uipc_msg.c
index cd41113..071e149 100644
--- a/sys/kern/uipc_msg.c
+++ b/sys/kern/uipc_msg.c
@@ -47,6 +47,8 @@
 #include <vm/pmap.h>
 #include <net/netmsg2.h>
 
+#include <machine/vmparam.h>
+
 #include <net/netisr.h>
 #include <net/netmsg.h>
 
@@ -414,7 +416,7 @@ so_pru_ctloutput(struct socket *so, struct sockopt *sopt)
 	lwkt_port_t port;
 	int error;
 
-	KKASSERT(!sopt->sopt_val || kva_p(sopt->sopt_val));
+	KKASSERT(sopt->sopt_val && (kva_p(sopt->sopt_val) || (vm_offset_t)(sopt->sopt_val) < USRSTACK));
 	port = so->so_proto->pr_mport(so, NULL, NULL, PRU_CTLOUTPUT);
 	netmsg_init(&msg.nm_netmsg, &curthread->td_msgport, 0,
 		    netmsg_pru_ctloutput);
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index f485de3..34e861d 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -100,6 +100,8 @@
 
 #include <machine/limits.h>
 
+#include <machine/vmparam.h>
+
 #ifdef INET
 static int	 do_setopt_accept_filter(struct socket *so, struct sockopt *sopt);
 #endif /* INET */
@@ -1260,8 +1262,8 @@ soopt_to_kbuf(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
 {
 	size_t	valsize;
 
-	KKASSERT(!sopt->sopt_val || kva_p(sopt->sopt_val));
-	KKASSERT(kva_p(buf));
+	KKASSERT(sopt->sopt_val && (kva_p(sopt->sopt_val) || (vm_offset_t)(sopt->sopt_val) < USRSTACK));
+	KKASSERT(kva_p(buf) || (vm_offset_t)(buf) < USRSTACK);
 
 	/*
 	 * If the user gives us more than we wanted, we ignore it,
@@ -1438,8 +1440,8 @@ soopt_from_kbuf(struct sockopt *sopt, const void *buf, size_t len)
 {
 	size_t	valsize;
 
-	KKASSERT(!sopt->sopt_val || kva_p(sopt->sopt_val));
-	KKASSERT(kva_p(buf));
+	KKASSERT(sopt->sopt_val && (kva_p(sopt->sopt_val) || (vm_offset_t)(sopt->sopt_val) < USRSTACK));
+	KKASSERT(kva_p(buf) || (vm_offset_t)(buf) < USRSTACK);
 
 	/*
 	 * Documented get behavior is that we always return a value,
@@ -1600,8 +1602,8 @@ soopt_to_mbuf(struct sockopt *sopt, struct mbuf *m)
 	size_t valsize;
 	void *val;
 
-	KKASSERT(!sopt->sopt_val || kva_p(sopt->sopt_val));
-	KKASSERT(kva_p(m));
+	KKASSERT(sopt->sopt_val && (kva_p(sopt->sopt_val) || (vm_offset_t)(sopt->sopt_val) < USRSTACK));
+	KKASSERT(kva_p(m) || (vm_offset_t)(m) < USRSTACK);
 	if (sopt->sopt_val == NULL)
 		return;
 	val = sopt->sopt_val;
@@ -1631,8 +1633,8 @@ soopt_from_mbuf(struct sockopt *sopt, struct mbuf *m)
 	size_t maxsize;
 	void *val;
 
-	KKASSERT(!sopt->sopt_val || kva_p(sopt->sopt_val));
-	KKASSERT(kva_p(m));
+	KKASSERT(sopt->sopt_val && (kva_p(sopt->sopt_val) || (vm_offset_t)(sopt->sopt_val) < USRSTACK));
+	KKASSERT(kva_p(m) || (vm_offset_t)(m) < USRSTACK);
 	if (sopt->sopt_val == NULL)
 		return 0;
 	val = sopt->sopt_val;





More information about the Bugs mailing list