diff mbox series

[net-next,v6,03/11] ipv4/route: Allow NULL flowinfo in rt_fill_info()

Message ID 5ba00822d7e86cdcb9231b39fda3cc4a04e2836f.1560987611.git.sbrivio@redhat.com
State Changes Requested
Delegated to: David Miller
Headers show
Series Fix listing (IPv4, IPv6) and flushing (IPv6) of cached route exceptions | expand

Commit Message

Stefano Brivio June 19, 2019, 11:59 p.m. UTC
In the next patch, we're going to use rt_fill_info() to dump exception
routes upon RTM_GETROUTE with NLM_F_ROOT, meaning userspace is requesting
a dump and not a specific route selection, which in turn implies the input
interface is not relevant. Update rt_fill_info() to handle a NULL
flowinfo.

Suggested-by: David Ahern <dsahern@gmail.com>
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
---
v6: New patch

 net/ipv4/route.c | 57 ++++++++++++++++++++++++++----------------------
 1 file changed, 31 insertions(+), 26 deletions(-)

Comments

David Ahern June 20, 2019, 1:15 p.m. UTC | #1
On 6/19/19 5:59 PM, Stefano Brivio wrote:
> In the next patch, we're going to use rt_fill_info() to dump exception
> routes upon RTM_GETROUTE with NLM_F_ROOT, meaning userspace is requesting
> a dump and not a specific route selection, which in turn implies the input
> interface is not relevant. Update rt_fill_info() to handle a NULL
> flowinfo.
> 
> Suggested-by: David Ahern <dsahern@gmail.com>
> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
> ---
> v6: New patch
> 
>  net/ipv4/route.c | 57 ++++++++++++++++++++++++++----------------------
>  1 file changed, 31 insertions(+), 26 deletions(-)
> 
> diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> index 66cbe8a7a168..052a80373b1d 100644
> --- a/net/ipv4/route.c
> +++ b/net/ipv4/route.c
> @@ -2699,7 +2699,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
>  	r->rtm_family	 = AF_INET;
>  	r->rtm_dst_len	= 32;
>  	r->rtm_src_len	= 0;
> -	r->rtm_tos	= fl4->flowi4_tos;
> +	if (fl4)
> +		r->rtm_tos	= fl4->flowi4_tos;

tracing back to the alloc_skb it does not appear to be initialized to 0,
so this should be:
	r->rtm_tos	= fl4 ? fl4->flowi4_tos : 0;


other than that it looks fine to me.

Reviewed-by: David Ahern <dsahern@gmail.com>
Stefano Brivio June 20, 2019, 7 p.m. UTC | #2
On Thu, 20 Jun 2019 07:15:55 -0600
David Ahern <dsahern@gmail.com> wrote:

> On 6/19/19 5:59 PM, Stefano Brivio wrote:
> > In the next patch, we're going to use rt_fill_info() to dump exception
> > routes upon RTM_GETROUTE with NLM_F_ROOT, meaning userspace is requesting
> > a dump and not a specific route selection, which in turn implies the input
> > interface is not relevant. Update rt_fill_info() to handle a NULL
> > flowinfo.
> > 
> > Suggested-by: David Ahern <dsahern@gmail.com>
> > Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
> > ---
> > v6: New patch
> > 
> >  net/ipv4/route.c | 57 ++++++++++++++++++++++++++----------------------
> >  1 file changed, 31 insertions(+), 26 deletions(-)
> > 
> > diff --git a/net/ipv4/route.c b/net/ipv4/route.c
> > index 66cbe8a7a168..052a80373b1d 100644
> > --- a/net/ipv4/route.c
> > +++ b/net/ipv4/route.c
> > @@ -2699,7 +2699,8 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
> >  	r->rtm_family	 = AF_INET;
> >  	r->rtm_dst_len	= 32;
> >  	r->rtm_src_len	= 0;
> > -	r->rtm_tos	= fl4->flowi4_tos;
> > +	if (fl4)
> > +		r->rtm_tos	= fl4->flowi4_tos;  
> 
> tracing back to the alloc_skb it does not appear to be initialized to 0,
> so this should be:
> 	r->rtm_tos	= fl4 ? fl4->flowi4_tos : 0;

I guess you're right, but I'm still wondering why I'm not seeing it
with KMSAN. Thanks for catching this, I'll fix it.
diff mbox series

Patch

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 66cbe8a7a168..052a80373b1d 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2699,7 +2699,8 @@  static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
 	r->rtm_family	 = AF_INET;
 	r->rtm_dst_len	= 32;
 	r->rtm_src_len	= 0;
-	r->rtm_tos	= fl4->flowi4_tos;
+	if (fl4)
+		r->rtm_tos	= fl4->flowi4_tos;
 	r->rtm_table	= table_id < 256 ? table_id : RT_TABLE_COMPAT;
 	if (nla_put_u32(skb, RTA_TABLE, table_id))
 		goto nla_put_failure;
@@ -2727,7 +2728,7 @@  static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
 	    nla_put_u32(skb, RTA_FLOW, rt->dst.tclassid))
 		goto nla_put_failure;
 #endif
-	if (!rt_is_input_route(rt) &&
+	if (fl4 && !rt_is_input_route(rt) &&
 	    fl4->saddr != src) {
 		if (nla_put_in_addr(skb, RTA_PREFSRC, fl4->saddr))
 			goto nla_put_failure;
@@ -2767,36 +2768,40 @@  static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
 	if (rtnetlink_put_metrics(skb, metrics) < 0)
 		goto nla_put_failure;
 
-	if (fl4->flowi4_mark &&
-	    nla_put_u32(skb, RTA_MARK, fl4->flowi4_mark))
-		goto nla_put_failure;
-
-	if (!uid_eq(fl4->flowi4_uid, INVALID_UID) &&
-	    nla_put_u32(skb, RTA_UID,
-			from_kuid_munged(current_user_ns(), fl4->flowi4_uid)))
-		goto nla_put_failure;
+	if (fl4) {
+		if (fl4->flowi4_mark &&
+		    nla_put_u32(skb, RTA_MARK, fl4->flowi4_mark))
+			goto nla_put_failure;
 
-	error = rt->dst.error;
+		if (!uid_eq(fl4->flowi4_uid, INVALID_UID) &&
+		    nla_put_u32(skb, RTA_UID,
+				from_kuid_munged(current_user_ns(),
+						 fl4->flowi4_uid)))
+			goto nla_put_failure;
 
-	if (rt_is_input_route(rt)) {
+		if (rt_is_input_route(rt)) {
 #ifdef CONFIG_IP_MROUTE
-		if (ipv4_is_multicast(dst) && !ipv4_is_local_multicast(dst) &&
-		    IPV4_DEVCONF_ALL(net, MC_FORWARDING)) {
-			int err = ipmr_get_route(net, skb,
-						 fl4->saddr, fl4->daddr,
-						 r, portid);
-
-			if (err <= 0) {
-				if (err == 0)
-					return 0;
-				goto nla_put_failure;
-			}
-		} else
+			if (ipv4_is_multicast(dst) &&
+			    !ipv4_is_local_multicast(dst) &&
+			    IPV4_DEVCONF_ALL(net, MC_FORWARDING)) {
+				int err = ipmr_get_route(net, skb,
+							 fl4->saddr, fl4->daddr,
+							 r, portid);
+
+				if (err <= 0) {
+					if (err == 0)
+						return 0;
+					goto nla_put_failure;
+				}
+			} else
 #endif
-			if (nla_put_u32(skb, RTA_IIF, fl4->flowi4_iif))
-				goto nla_put_failure;
+				if (nla_put_u32(skb, RTA_IIF, fl4->flowi4_iif))
+					goto nla_put_failure;
+		}
 	}
 
+	error = rt->dst.error;
+
 	if (rtnl_put_cacheinfo(skb, &rt->dst, 0, expires, error) < 0)
 		goto nla_put_failure;