Re: ip_icmp reference fix

2016-08-22 Thread Claudio Jeker
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 -  1.56
> +++ netmpls/mpls_input.c  22 Aug 2016 11:20:48 -
> @@ -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 -   1.151
> +++ netinet/ip_icmp.c 22 Aug 2016 11:21:02 -
> @@ -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



Re: ip_icmp reference fix

2016-08-22 Thread Alexander Bluhm
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?

OK bluhm@

> 
> 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 -  1.56
> +++ netmpls/mpls_input.c  22 Aug 2016 11:20:48 -
> @@ -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 -   1.151
> +++ netinet/ip_icmp.c 22 Aug 2016 11:21:02 -
> @@ -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;



Re: ip_icmp reference fix

2016-08-22 Thread Jeremie Courreges-Anglas
Martin Pieuchot  writes:

> 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?

ok jca@

-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE



ip_icmp reference fix

2016-08-22 Thread Martin Pieuchot
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?

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.c11 Jul 2016 09:23:06 -  1.56
+++ netmpls/mpls_input.c22 Aug 2016 11:20:48 -
@@ -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 -   1.151
+++ netinet/ip_icmp.c   22 Aug 2016 11:21:02 -
@@ -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;