Previously reported by bluhm@, the code paths in so{s,g}etopt() also
need to be executed at IPL_SOFTNET in order to get rid of the recursive
splsoftnet/splx dances in other places.

ok?

Index: kern/uipc_syscalls.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
retrieving revision 1.140
diff -u -p -r1.140 uipc_syscalls.c
--- kern/uipc_syscalls.c        21 Nov 2016 09:09:06 -0000      1.140
+++ kern/uipc_syscalls.c        21 Nov 2016 11:23:44 -0000
@@ -966,7 +966,7 @@ sys_setsockopt(struct proc *p, void *v, 
        } */ *uap = v;
        struct file *fp;
        struct mbuf *m = NULL;
-       int error;
+       int s, error;
 
 
        if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
@@ -998,7 +998,9 @@ sys_setsockopt(struct proc *p, void *v, 
                }
                m->m_len = SCARG(uap, valsize);
        }
+       s = splsoftnet();
        error = sosetopt(fp->f_data, SCARG(uap, level), SCARG(uap, name), m);
+       splx(s);
        m = NULL;
 bad:
        if (m)
@@ -1020,7 +1022,7 @@ sys_getsockopt(struct proc *p, void *v, 
        struct file *fp;
        struct mbuf *m = NULL;
        socklen_t valsize;
-       int error;
+       int s, error;
 
        if ((error = getsock(p, SCARG(uap, s), &fp)) != 0)
                return (error);
@@ -1034,8 +1036,11 @@ sys_getsockopt(struct proc *p, void *v, 
                        goto out;
        } else
                valsize = 0;
-       if ((error = sogetopt(fp->f_data, SCARG(uap, level),
-           SCARG(uap, name), &m)) == 0 && SCARG(uap, val) && valsize &&
+
+       s = splsoftnet();
+       error = sogetopt(fp->f_data, SCARG(uap, level), SCARG(uap, name), &m);
+       splx(s);
+       if (error == 0 && SCARG(uap, val) && valsize &&
            m != NULL) {
                if (valsize > m->m_len)
                        valsize = m->m_len;
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 11:22:42 -0000
@@ -1544,6 +1544,8 @@ sosetopt(struct socket *so, int level, i
        int error = 0;
        struct mbuf *m = m0;
 
+       splsoftassert(IPL_SOFTNET);
+
        if (level != SOL_SOCKET) {
                if (so->so_proto && so->so_proto->pr_ctloutput)
                        return ((*so->so_proto->pr_ctloutput)
@@ -1733,6 +1735,8 @@ int
 sogetopt(struct socket *so, int level, int optname, struct mbuf **mp)
 {
        struct mbuf *m;
+
+       splsoftassert(IPL_SOFTNET);
 
        if (level != SOL_SOCKET) {
                if (so->so_proto && so->so_proto->pr_ctloutput) {

Reply via email to