Hello,
pf_route() might leak a refence to ifp.
> Index: sys/net/pf.c
> ===================================================================
> RCS file: /cvs/src/sys/net/pf.c,v
> retrieving revision 1.1101
> diff -u -p -r1.1101 pf.c
> --- sys/net/pf.c 19 Jan 2021 22:22:23 -0000 1.1101
> +++ sys/net/pf.c 22 Jan 2021 07:33:31 -0000
</snip>
> @@ -5998,48 +5994,40 @@ pf_route(struct pf_pdesc *pd, struct pf_
>
> ip = mtod(m0, struct ip *);
>
</snip>
> +
> + ifp = if_get(rt->rt_ifidx);
> if (ifp == NULL)
> goto bad;
here we get a reference to ifp.
>
> - if (pd->kif->pfik_ifp != ifp) {
> + /* A locally generated packet may have invalid source address. */
> + if ((ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET &&
> + (ifp->if_flags & IFF_LOOPBACK) == 0)
> + ip->ip_src = ifatoia(rt->rt_ifa)->ia_addr.sin_addr;
> +
> + if (pd->dir == PF_IN) {
> if (pf_test(AF_INET, PF_OUT, ifp, &m0) != PF_PASS)
> goto bad;
> else if (m0 == NULL)
> @@ -6052,16 +6040,6 @@ pf_route(struct pf_pdesc *pd, struct pf_
> ip = mtod(m0, struct ip *);
> }
>
> - rt = rtalloc(sintosa(dst), RT_RESOLVE, rtableid);
> - if (!rtisvalid(rt)) {
> - ipstat_inc(ips_noroute);
> - goto bad;
> - }
> - /* A locally generated packet may have invalid source address. */
> - if ((ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET &&
> - (ifp->if_flags & IFF_LOOPBACK) == 0)
> - ip->ip_src = ifatoia(rt->rt_ifa)->ia_addr.sin_addr;
> -
> in_proto_cksum_out(m0, ifp);
>
> if (ntohs(ip->ip_len) <= ifp->if_mtu) {
> @@ -6082,9 +6060,9 @@ pf_route(struct pf_pdesc *pd, struct pf_
> */
> if (ip->ip_off & htons(IP_DF)) {
> ipstat_inc(ips_cantfrag);
> - if (r->rt != PF_DUPTO)
> + if (s->rt != PF_DUPTO)
> pf_send_icmp(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG,
> - ifp->if_mtu, pd->af, r, pd->rdomain);
> + ifp->if_mtu, pd->af, s->rule.ptr, pd->rdomain);
> goto bad;
here we do 'goto bad', which does not call if_put().
> }
>
> @@ -6108,8 +6086,9 @@ pf_route(struct pf_pdesc *pd, struct pf_
> ipstat_inc(ips_fragmented);
>
> done:
> - if (r->rt != PF_DUPTO)
> + if (s->rt != PF_DUPTO)
> pd->m = NULL;
> + if_put(ifp);
> rtfree(rt);
> return;
>
pf_route6() suffers from the same issue.
thanks and
regards
sashan