On Mon, Aug 22, 2016 at 01:21:47PM +0200, Martin Pieuchot wrote:
> When it comes to reference counting in the receiving path, route entries
> act as proxy for interface addresses.  In other words you CANNOT
> dereference ``rt->rt_ifa'' after calling rtfree(9).
> 
> Diff below fixes that in icmp_reflect(), ok?

Good catch.
OK claudio@
 
> Index: netmpls/mpls_input.c
> ===================================================================
> RCS file: /cvs/src/sys/netmpls/mpls_input.c,v
> retrieving revision 1.56
> diff -u -p -r1.56 mpls_input.c
> --- netmpls/mpls_input.c      11 Jul 2016 09:23:06 -0000      1.56
> +++ netmpls/mpls_input.c      22 Aug 2016 11:20:48 -0000
> @@ -385,8 +385,9 @@ mpls_do_error(struct mbuf *m, int type, 
>                       m_freem(m);
>                       return (NULL);
>               }
> -             rtfree(rt);
> +             /* It is safe to dereference ``ia'' iff ``rt'' is valid. */
>               error = icmp_reflect(m, NULL, ia);
> +             rtfree(rt);
>               if (error)
>                       return (NULL);
>  
> Index: netinet/ip_icmp.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_icmp.c,v
> retrieving revision 1.151
> diff -u -p -r1.151 ip_icmp.c
> --- netinet/ip_icmp.c 9 Dec 2015 09:27:40 -0000       1.151
> +++ netinet/ip_icmp.c 22 Aug 2016 11:21:02 -0000
> @@ -702,7 +702,7 @@ icmp_reflect(struct mbuf *m, struct mbuf
>       struct ip *ip = mtod(m, struct ip *);
>       struct mbuf *opts = NULL;
>       struct sockaddr_in sin;
> -     struct rtentry *rt;
> +     struct rtentry *rt = NULL;
>       int optlen = (ip->ip_hl << 2) - sizeof(struct ip);
>       u_int rtableid;
>  
> @@ -733,7 +733,6 @@ icmp_reflect(struct mbuf *m, struct mbuf
>               if (rtisvalid(rt) &&
>                   ISSET(rt->rt_flags, RTF_LOCAL|RTF_BROADCAST))
>                       ia = ifatoia(rt->rt_ifa);
> -             rtfree(rt);
>       }
>  
>       /*
> @@ -742,6 +741,8 @@ icmp_reflect(struct mbuf *m, struct mbuf
>        * drop the packet as there is no path to the host.
>        */
>       if (ia == NULL) {
> +             rtfree(rt);
> +
>               memset(&sin, 0, sizeof(sin));
>               sin.sin_len = sizeof(sin);
>               sin.sin_family = AF_INET;
> @@ -756,12 +757,14 @@ icmp_reflect(struct mbuf *m, struct mbuf
>               }
>  
>               ia = ifatoia(rt->rt_ifa);
> -             rtfree(rt);
>       }
>  
>       ip->ip_dst = ip->ip_src;
> -     ip->ip_src = ia->ia_addr.sin_addr;
>       ip->ip_ttl = MAXTTL;
> +
> +     /* It is safe to dereference ``ia'' iff ``rt'' is valid. */
> +     ip->ip_src = ia->ia_addr.sin_addr;
> +     rtfree(rt);
>  
>       if (optlen > 0) {
>               u_char *cp;
> 

-- 
:wq Claudio

Reply via email to