Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Fix race condition on the rawcb list shared by rtsock an...



details:   https://anonhg.NetBSD.org/src/rev/94d50eacbe19
branches:  trunk
changeset: 826727:94d50eacbe19
user:      ozaki-r <ozaki-r%NetBSD.org@localhost>
date:      Mon Sep 25 01:56:22 2017 +0000

description:
Fix race condition on the rawcb list shared by rtsock and keysock

keysock now protects itself by its own mutex, which means that
the rawcb list is protected by two different mutexes (keysock's one
and softnet_lock for rtsock), of course it's useless.

Fix the situation by having a discrete rawcb list for each.

diffstat:

 sys/net/raw_cb.c       |  10 ++++------
 sys/net/raw_cb.h       |   6 ++----
 sys/net/raw_usrreq.c   |  14 +++++---------
 sys/net/rtsock.c       |  19 +++++++++++++------
 sys/netipsec/keysock.c |  18 +++++++++++++-----
 5 files changed, 37 insertions(+), 30 deletions(-)

diffs (256 lines):

diff -r 0a089029a616 -r 94d50eacbe19 sys/net/raw_cb.c
--- a/sys/net/raw_cb.c  Mon Sep 25 00:12:21 2017 +0000
+++ b/sys/net/raw_cb.c  Mon Sep 25 01:56:22 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: raw_cb.c,v 1.23 2017/07/27 09:53:57 ozaki-r Exp $      */
+/*     $NetBSD: raw_cb.c,v 1.24 2017/09/25 01:56:22 ozaki-r Exp $      */
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_cb.c,v 1.23 2017/07/27 09:53:57 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_cb.c,v 1.24 2017/09/25 01:56:22 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,8 +57,6 @@
  *     redo address binding to allow wildcards
  */
 
-struct rawcbhead       rawcb = LIST_HEAD_INITIALIZER(rawcb);
-
 static u_long          raw_sendspace = RAWSNDQ;
 static u_long          raw_recvspace = RAWRCVQ;
 
@@ -66,7 +64,7 @@
  * Allocate a nominal amount of buffer space for the socket.
  */
 int
-raw_attach(struct socket *so, int proto)
+raw_attach(struct socket *so, int proto, struct rawcbhead *rawcbhead)
 {
        struct rawcb *rp;
        int error;
@@ -87,7 +85,7 @@
        rp->rcb_socket = so;
        rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
        rp->rcb_proto.sp_protocol = proto;
-       LIST_INSERT_HEAD(&rawcb, rp, rcb_list);
+       LIST_INSERT_HEAD(rawcbhead, rp, rcb_list);
        KASSERT(solocked(so));
 
        return 0;
diff -r 0a089029a616 -r 94d50eacbe19 sys/net/raw_cb.h
--- a/sys/net/raw_cb.h  Mon Sep 25 00:12:21 2017 +0000
+++ b/sys/net/raw_cb.h  Mon Sep 25 01:56:22 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: raw_cb.h,v 1.27 2017/04/11 13:55:54 roy Exp $  */
+/*     $NetBSD: raw_cb.h,v 1.28 2017/09/25 01:56:22 ozaki-r Exp $      */
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -60,13 +60,11 @@
 #define        RAWRCVQ         8192
 
 LIST_HEAD(rawcbhead, rawcb);
-extern struct  rawcbhead rawcb;                /* head of list */
 
-int    raw_attach(struct socket *, int);
+int    raw_attach(struct socket *, int, struct rawcbhead *);
 void   *raw_ctlinput(int, const struct sockaddr *, void *);
 void   raw_detach(struct socket *);
 void   raw_disconnect(struct rawcb *);
-void   raw_init(void);
 void   raw_input(struct mbuf *, ...);
 int    raw_usrreq(struct socket *,
            int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *);
diff -r 0a089029a616 -r 94d50eacbe19 sys/net/raw_usrreq.c
--- a/sys/net/raw_usrreq.c      Mon Sep 25 00:12:21 2017 +0000
+++ b/sys/net/raw_usrreq.c      Mon Sep 25 01:56:22 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: raw_usrreq.c,v 1.56 2017/04/11 13:55:54 roy Exp $      */
+/*     $NetBSD: raw_usrreq.c,v 1.57 2017/09/25 01:56:22 ozaki-r Exp $  */
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.56 2017/04/11 13:55:54 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.57 2017/09/25 01:56:22 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/mbuf.h>
@@ -54,12 +54,6 @@
 #include <net/netisr.h>
 #include <net/raw_cb.h>
 
-void
-raw_init(void)
-{
-       LIST_INIT(&rawcb);
-}
-
 static inline int
 equal(const struct sockaddr *a1, const struct sockaddr *a2)
 {
@@ -79,6 +73,7 @@
        va_list ap;
        struct sockproto *proto;
        struct sockaddr *src, *dst;
+       struct rawcbhead *rawcbhead;
 
        KASSERT(mutex_owned(softnet_lock));
 
@@ -86,10 +81,11 @@
        proto = va_arg(ap, struct sockproto *);
        src = va_arg(ap, struct sockaddr *);
        dst = va_arg(ap, struct sockaddr *);
+       rawcbhead = va_arg(ap, struct rawcbhead *);
        va_end(ap);
 
        last = NULL;
-       LIST_FOREACH(rp, &rawcb, rcb_list) {
+       LIST_FOREACH(rp, rawcbhead, rcb_list) {
                if (rp->rcb_proto.sp_family != proto->sp_family)
                        continue;
                if (rp->rcb_proto.sp_protocol  &&
diff -r 0a089029a616 -r 94d50eacbe19 sys/net/rtsock.c
--- a/sys/net/rtsock.c  Mon Sep 25 00:12:21 2017 +0000
+++ b/sys/net/rtsock.c  Mon Sep 25 01:56:22 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtsock.c,v 1.227 2017/07/01 16:59:12 christos Exp $    */
+/*     $NetBSD: rtsock.c,v 1.228 2017/09/25 01:56:22 ozaki-r Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.227 2017/07/01 16:59:12 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.228 2017/09/25 01:56:22 ozaki-r Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -239,6 +239,13 @@
        return 0;
 }
 
+static void
+rt_pr_init(void)
+{
+
+       LIST_INIT(&rt_rawcb);
+}
+
 static int
 COMPATNAME(route_attach)(struct socket *so, int proto)
 {
@@ -253,7 +260,7 @@
        so->so_pcb = rp;
 
        s = splsoftnet();
-       if ((error = raw_attach(so, proto)) == 0) {
+       if ((error = raw_attach(so, proto, &rt_rawcb)) == 0) {
                rt_adjustcount(rp->rcb_proto.sp_protocol, 1);
                rp->rcb_laddr = &COMPATNAME(route_info).ri_src;
                rp->rcb_faddr = &COMPATNAME(route_info).ri_dst;
@@ -1045,7 +1052,7 @@
                proto.sp_protocol = family;
        if (m)
                raw_input(m, &proto, &COMPATNAME(route_info).ri_src,
-                   &COMPATNAME(route_info).ri_dst);
+                   &COMPATNAME(route_info).ri_dst, &rt_rawcb);
        if (rp)
                rp->rcb_proto.sp_family = PF_XROUTE;
     }
@@ -2027,7 +2034,7 @@
                if (m == NULL)
                        break;
                proto.sp_protocol = M_GETCTX(m, uintptr_t);
-               raw_input(m, &proto, &ri->ri_src, &ri->ri_dst);
+               raw_input(m, &proto, &ri->ri_src, &ri->ri_dst, &rt_rawcb);
        }
        KERNEL_UNLOCK_ONE(NULL);
        mutex_exit(softnet_lock);
@@ -2116,7 +2123,7 @@
                .pr_ctlinput = raw_ctlinput,
                .pr_ctloutput = route_ctloutput,
                .pr_usrreqs = &route_usrreqs,
-               .pr_init = raw_init,
+               .pr_init = rt_pr_init,
        },
 };
 
diff -r 0a089029a616 -r 94d50eacbe19 sys/netipsec/keysock.c
--- a/sys/netipsec/keysock.c    Mon Sep 25 00:12:21 2017 +0000
+++ b/sys/netipsec/keysock.c    Mon Sep 25 01:56:22 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: keysock.c,v 1.60 2017/08/08 10:41:33 ozaki-r Exp $     */
+/*     $NetBSD: keysock.c,v 1.61 2017/09/25 01:56:22 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.60 2017/08/08 10:41:33 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.61 2017/09/25 01:56:22 ozaki-r Exp $");
 
 /* This code has derived from sys/net/rtsock.c on FreeBSD2.2.5 */
 
@@ -84,6 +84,7 @@
 int key_registered_sb_max = (2048 * MHLEN); /* XXX arbitrary */
 
 static kmutex_t *key_so_mtx;
+static struct rawcbhead key_rawcb;
 
 void
 key_init_so(void)
@@ -92,6 +93,13 @@
        key_so_mtx = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
 }
 
+static void
+key_pr_init(void)
+{
+
+       LIST_INIT(&key_rawcb);
+}
+
 /*
  * key_output()
  */
@@ -352,7 +360,7 @@
                PFKEY_STATINC(PFKEY_STAT_IN_MSGTYPE + msg->sadb_msg_type);
        }
 
-       LIST_FOREACH(rp, &rawcb, rcb_list)
+       LIST_FOREACH(rp, &key_rawcb, rcb_list)
        {
                struct socket * kso = rp->rcb_socket;
                if (rp->rcb_proto.sp_family != PF_KEY)
@@ -469,7 +477,7 @@
        so->so_lock = key_so_mtx;
        solock(so);
 
-       error = raw_attach(so, proto);
+       error = raw_attach(so, proto, &key_rawcb);
        if (error) {
                PFKEY_STATINC(PFKEY_STAT_SOCKERR);
                kmem_free(kp, sizeof(*kp));
@@ -753,7 +761,7 @@
        .pr_flags = PR_ATOMIC|PR_ADDR,
        .pr_ctlinput = raw_ctlinput,
        .pr_usrreqs = &key_usrreqs,
-       .pr_init = raw_init,
+       .pr_init = key_pr_init,
     }
 };
 



Home | Main Index | Thread Index | Old Index