network - Fixes for wpa, general sockets.
authorMatthew Dillon <dillon@laptop2.(none)>
Sat, 11 Sep 2010 09:32:24 +0000 (09:32 +0000)
committerMatthew Dillon <dillon@laptop2.(none)>
Sat, 11 Sep 2010 09:32:24 +0000 (09:32 +0000)
* netisr_characterize() was not properly handling unknown
  characterizations (array overflow).

* The raw protocol was not MPSAFE.

* Protect kqinfo->ki_mlist in sowakeup

sys/kern/uipc_socket2.c
sys/net/netisr.c
sys/net/raw_usrreq.c

index 4369da5..9abd2ae 100644 (file)
@@ -468,6 +468,7 @@ sowakeup(struct socket *so, struct signalsockbuf *ssb)
        if (ssb->ssb_flags & SSB_MEVENT) {
                struct netmsg_so_notify *msg, *nmsg;
 
+               lwkt_gettoken(&kq_token);
                TAILQ_FOREACH_MUTABLE(msg, &kqinfo->ki_mlist, nm_list, nmsg) {
                        if (msg->nm_predicate(&msg->nm_netmsg)) {
                                TAILQ_REMOVE(&kqinfo->ki_mlist, msg, nm_list);
@@ -477,6 +478,7 @@ sowakeup(struct socket *so, struct signalsockbuf *ssb)
                }
                if (TAILQ_EMPTY(&ssb->ssb_kq.ki_mlist))
                        atomic_clear_int(&ssb->ssb_flags, SSB_MEVENT);
+               lwkt_reltoken(&kq_token);
        }
 }
 
index baf005e..cfa4866 100644 (file)
@@ -357,11 +357,18 @@ netisr_characterize(int num, struct mbuf **mp, int hoff)
        /*
         * Validation
         */
-       KASSERT((num > 0 && num <= (sizeof(netisrs)/sizeof(netisrs[0]))),
-               ("Bad isr %d", num));
        m = *mp;
        KKASSERT(m != NULL);
 
+       if (num < 0 || num >= NETISR_MAX) {
+               if (num == NETISR_MAX) {
+                       m->m_flags |= M_HASH;
+                       m->m_pkthdr.hash = 0;
+                       return;
+               }
+               panic("Bad isr %d", num);
+       }
+
        /*
         * Valid netisr?
         */
index 1e87404..8c232b6 100644 (file)
@@ -48,6 +48,9 @@
 
 #include <net/raw_cb.h>
 
+
+static struct lwkt_token raw_token = LWKT_TOKEN_MP_INITIALIZER(raw_token);
+
 /*
  * Initialize raw connection block q.
  */
@@ -78,6 +81,8 @@ raw_input(struct mbuf *m0, const struct sockproto *proto,
        struct mbuf *m = m0;
        struct socket *last;
 
+       lwkt_gettoken(&raw_token);
+
        last = NULL;
        LIST_FOREACH(rp, &rawcb_list, list) {
                if (rp == skip)
@@ -123,6 +128,7 @@ raw_input(struct mbuf *m0, const struct sockproto *proto,
        } else {
                m_freem(m);
        }
+       lwkt_reltoken(&raw_token);
 }
 
 /*ARGSUSED*/