On Mon, Jul 24, 2017 at 12:54:31PM +0200, Martin Pieuchot wrote:
> divert/divert6 might end up calling sorwakeup() w/o KERNEL_LOCK() since
> pf_test() is not always executed with it. Diff below fixes that and
> put two asserts where selwakup() is called in the socket layer.
I think calling divert_packet() directly from pf_test() is a layer
violation. It would be better to add a mbuf tag in pf and process
divert-packet at the protocol delivery loop. Then divert_packet()
could be a regular pr_input function and work more like divert-to.
I will try to do something like this. Then we can deal with
sorwakeup() in all pr_input funtions the same way. We still have
to find a general solution.
> ok?
You diff is a quick fix for an actual problem. Let's move forward.
OK bluhm@
> Index: kern/uipc_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.196
> diff -u -p -r1.196 uipc_socket.c
> --- kern/uipc_socket.c 20 Jul 2017 09:49:45 -0000 1.196
> +++ kern/uipc_socket.c 24 Jul 2017 10:33:56 -0000
> @@ -1926,6 +1926,7 @@ sogetopt(struct socket *so, int level, i
> void
> sohasoutofband(struct socket *so)
> {
> + KERNEL_ASSERT_LOCKED();
> csignal(so->so_pgid, SIGURG, so->so_siguid, so->so_sigeuid);
> selwakeup(&so->so_rcv.sb_sel);
> }
> Index: kern/uipc_socket2.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
> retrieving revision 1.84
> diff -u -p -r1.84 uipc_socket2.c
> --- kern/uipc_socket2.c 18 Jul 2017 06:12:09 -0000 1.84
> +++ kern/uipc_socket2.c 24 Jul 2017 10:49:12 -0000
> @@ -382,6 +382,7 @@ sbunlock(struct sockbuf *sb)
> void
> sowakeup(struct socket *so, struct sockbuf *sb)
> {
> + KERNEL_ASSERT_LOCKED();
> soassertlocked(so);
>
> selwakeup(&sb->sb_sel);
> Index: netinet/ip_divert.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_divert.c,v
> retrieving revision 1.48
> diff -u -p -r1.48 ip_divert.c
> --- netinet/ip_divert.c 26 Jun 2017 09:32:32 -0000 1.48
> +++ netinet/ip_divert.c 24 Jul 2017 10:44:39 -0000
> @@ -226,8 +226,11 @@ divert_packet(struct mbuf *m, int dir, u
> divstat_inc(divs_fullsock);
> m_freem(m);
> return (0);
> - } else
> + } else {
> + KERNEL_LOCK();
> sorwakeup(inp->inp_socket);
> + KERNEL_UNLOCK();
> + }
> }
>
> if (sa == NULL) {
> Index: netinet6/ip6_divert.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/ip6_divert.c,v
> retrieving revision 1.48
> diff -u -p -r1.48 ip6_divert.c
> --- netinet6/ip6_divert.c 26 Jun 2017 09:32:32 -0000 1.48
> +++ netinet6/ip6_divert.c 24 Jul 2017 10:44:36 -0000
> @@ -227,8 +227,11 @@ divert6_packet(struct mbuf *m, int dir,
> div6stat_inc(div6s_fullsock);
> m_freem(m);
> return (0);
> - } else
> + } else {
> + KERNEL_LOCK();
> sorwakeup(inp->inp_socket);
> + KERNEL_UNLOCK();
> + }
> }
>
> if (sa == NULL) {