On 21/11/16(Mon) 15:17, Alexander Bluhm wrote:
> [...] 
> There are a bunch of calls to sosetopt() in bfd and nfs that are
> not protected by splsoftnet().

Indeed.  Then I believe putting the splsoftnet() inside sosetopt() is
a better solution.

Index: kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.165
diff -u -p -r1.165 uipc_socket.c
--- kern/uipc_socket.c  21 Nov 2016 09:09:06 -0000      1.165
+++ kern/uipc_socket.c  21 Nov 2016 14:47:01 -0000
@@ -1541,13 +1541,17 @@ sowwakeup(struct socket *so)
 int
 sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
 {
-       int error = 0;
+       int s, error = 0;
        struct mbuf *m = m0;
 
        if (level != SOL_SOCKET) {
-               if (so->so_proto && so->so_proto->pr_ctloutput)
-                       return ((*so->so_proto->pr_ctloutput)
-                                 (PRCO_SETOPT, so, level, optname, &m0));
+               if (so->so_proto && so->so_proto->pr_ctloutput) {
+                       s = splsoftnet();
+                       error = (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
+                           level, optname, &m0);
+                       splx(s);
+                       return (error);
+               }
                error = ENOPROTOOPT;
        } else {
                switch (optname) {
@@ -1689,8 +1693,11 @@ sosetopt(struct socket *so, int level, i
                                struct domain *dom = so->so_proto->pr_domain;
 
                                level = dom->dom_protosw->pr_protocol;
-                               return ((*so->so_proto->pr_ctloutput)
-                                   (PRCO_SETOPT, so, level, optname, &m0));
+                               s = splsoftnet();
+                               error = (*so->so_proto->pr_ctloutput)
+                                   (PRCO_SETOPT, so, level, optname, &m0);
+                               splx(s);
+                               return (error);
                        }
                        error = ENOPROTOOPT;
                        break;
@@ -1718,8 +1725,10 @@ sosetopt(struct socket *so, int level, i
                        break;
                }
                if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
-                       (void) ((*so->so_proto->pr_ctloutput)
-                                 (PRCO_SETOPT, so, level, optname, &m0));
+                       s = splsoftnet();
+                       (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
+                           level, optname, &m0);
+                       splx(s);
                        m = NULL;       /* freed by protocol */
                }
        }
@@ -1732,12 +1741,16 @@ bad:
 int
 sogetopt(struct socket *so, int level, int optname, struct mbuf **mp)
 {
+       int s, error = 0;
        struct mbuf *m;
 
        if (level != SOL_SOCKET) {
                if (so->so_proto && so->so_proto->pr_ctloutput) {
-                       return ((*so->so_proto->pr_ctloutput)
-                                 (PRCO_GETOPT, so, level, optname, mp));
+                       s = splsoftnet();
+                       error = (*so->so_proto->pr_ctloutput)(PRCO_GETOPT, so,
+                           level, optname, mp);
+                       splx(s);
+                       return (error);
                } else
                        return (ENOPROTOOPT);
        } else {
@@ -1817,8 +1830,11 @@ sogetopt(struct socket *so, int level, i
                                struct domain *dom = so->so_proto->pr_domain;
 
                                level = dom->dom_protosw->pr_protocol;
-                               return ((*so->so_proto->pr_ctloutput)
-                                   (PRCO_GETOPT, so, level, optname, mp));
+                               s = splsoftnet();
+                               error = (*so->so_proto->pr_ctloutput)
+                                   (PRCO_GETOPT, so, level, optname, mp);
+                               splx(s);
+                               return (error);
                        }
                        return (ENOPROTOOPT);
                        break;

Reply via email to