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

Reply via email to