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) {