network - Fix tcp inpcb race
authorMatthew Dillon <dillon@apollo.backplane.com>
Sat, 11 Sep 2010 20:37:21 +0000 (13:37 -0700)
committerMatthew Dillon <dillon@laptop2.(none)>
Sat, 11 Sep 2010 20:40:33 +0000 (13:40 -0700)
* tcbinfo[cpu].porthashbase was being shared across all the cpus,
  creating MP races.  Change it so it isn't shared.

Reported-by: "Samuel J. Greear" <sjg@evilcode.net>
sys/netinet/tcp_subr.c

index ed7a9e8..5aae6e7 100644 (file)
@@ -317,8 +317,7 @@ struct      inp_tp {
 void
 tcp_init(void)
 {
-       struct inpcbporthead *porthashbase;
-       u_long porthashmask;
+       struct inpcbinfo *ticb;
        int hashsize = TCBHASHSIZE;
        int cpu;
 
@@ -344,18 +343,18 @@ tcp_init(void)
                hashsize = 512; /* safe default */
        }
        tcp_tcbhashsize = hashsize;
-       porthashbase = hashinit(hashsize, M_PCB, &porthashmask);
 
        for (cpu = 0; cpu < ncpus2; cpu++) {
-               in_pcbinfo_init(&tcbinfo[cpu]);
-               tcbinfo[cpu].cpu = cpu;
-               tcbinfo[cpu].hashbase = hashinit(hashsize, M_PCB,
-                   &tcbinfo[cpu].hashmask);
-               tcbinfo[cpu].porthashbase = porthashbase;
-               tcbinfo[cpu].porthashmask = porthashmask;
-               tcbinfo[cpu].wildcardhashbase = hashinit(hashsize, M_PCB,
-                   &tcbinfo[cpu].wildcardhashmask);
-               tcbinfo[cpu].ipi_size = sizeof(struct inp_tp);
+               ticb = &tcbinfo[cpu];
+               in_pcbinfo_init(ticb);
+               ticb->cpu = cpu;
+               ticb->hashbase = hashinit(hashsize, M_PCB,
+                                         &ticb->hashmask);
+               ticb->porthashbase = hashinit(hashsize, M_PCB,
+                                             &ticb->porthashmask);
+               ticb->wildcardhashbase = hashinit(hashsize, M_PCB,
+                                                 &ticb->wildcardhashmask);
+               ticb->ipi_size = sizeof(struct inp_tp);
                TAILQ_INIT(&tcpcbackq[cpu]);
        }