Alexander Bluhm([email protected]) on 2018.07.04 22:49:01 +0200:
> Hi,
>
> It was possible to leak the control mbuf in raw ip user request
> with sendmsg(2) and MSG_OOB. Sync the code in udp, rip, and
> rip6_usrreq. Add an inp NULL check in rip6_usrreq for consistency.
>
> ok?
ok
> bluhm
>
> Index: netinet/raw_ip.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/raw_ip.c,v
> retrieving revision 1.110
> diff -u -p -r1.110 raw_ip.c
> --- netinet/raw_ip.c 4 Jul 2018 02:08:13 -0000 1.110
> +++ netinet/raw_ip.c 4 Jul 2018 20:12:28 -0000
> @@ -365,7 +365,7 @@ int
> rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
> struct mbuf *control, struct proc *p)
> {
> - struct inpcb *inp = sotoinpcb(so);
> + struct inpcb *inp;
> int error = 0;
>
> if (req == PRU_CONTROL)
> @@ -374,6 +374,7 @@ rip_usrreq(struct socket *so, int req, s
>
> soassertlocked(so);
>
> + inp = sotoinpcb(so);
> if (inp == NULL) {
> error = EINVAL;
> goto release;
> @@ -504,6 +505,7 @@ rip_usrreq(struct socket *so, int req, s
> panic("rip_usrreq");
> }
> release:
> + m_freem(control);
> m_freem(m);
> return (error);
> }
> Index: netinet/udp_usrreq.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/udp_usrreq.c,v
> retrieving revision 1.249
> diff -u -p -r1.249 udp_usrreq.c
> --- netinet/udp_usrreq.c 8 Jun 2018 14:09:57 -0000 1.249
> +++ netinet/udp_usrreq.c 4 Jul 2018 20:09:46 -0000
> @@ -1203,7 +1203,6 @@ udp_usrreq(struct socket *so, int req, s
> default:
> panic("udp_usrreq");
> }
> -
> release:
> m_freem(control);
> m_freem(m);
> Index: netinet6/raw_ip6.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/raw_ip6.c,v
> retrieving revision 1.128
> diff -u -p -r1.128 raw_ip6.c
> --- netinet6/raw_ip6.c 4 Jul 2018 02:08:13 -0000 1.128
> +++ netinet6/raw_ip6.c 4 Jul 2018 20:40:05 -0000
> @@ -544,7 +544,7 @@ int
> rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
> struct mbuf *control, struct proc *p)
> {
> - struct inpcb *in6p = sotoinpcb(so);
> + struct inpcb *in6p;
> int error = 0;
>
> if (req == PRU_CONTROL)
> @@ -553,6 +553,12 @@ rip6_usrreq(struct socket *so, int req,
>
> soassertlocked(so);
>
> + in6p = sotoinpcb(so);
> + if (in6p == NULL) {
> + error = EINVAL;
> + goto release;
> + }
> +
> switch (req) {
> case PRU_DISCONNECT:
> if ((so->so_state & SS_ISCONNECTED) == 0) {
> @@ -654,6 +660,7 @@ rip6_usrreq(struct socket *so, int req,
> dst.sin6_scope_id = addr6->sin6_scope_id;
> }
> error = rip6_output(m, so, sin6tosa(&dst), control);
> + control = NULL;
> m = NULL;
> break;
> }
> @@ -687,6 +694,8 @@ rip6_usrreq(struct socket *so, int req,
> default:
> panic("rip6_usrreq");
> }
> +release:
> + m_freem(control);
> m_freem(m);
> return (error);
> }
>