lwtunnel: Validate RTA_ENCAP_TYPE attribute length
authorDavid Ahern <dsahern@kernel.org>
Fri, 31 Dec 2021 00:36:35 +0000 (17:36 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 Jan 2022 14:25:00 +0000 (15:25 +0100)
commit 8bda81a4d400cf8a72e554012f0d8c45e07a3904 upstream.

lwtunnel_valid_encap_type_attr is used to validate encap attributes
within a multipath route. Add length validation checking to the type.

lwtunnel_valid_encap_type_attr is called converting attributes to
fib{6,}_config struct which means it is used before fib_get_nhs,
ip6_route_multipath_add, and ip6_route_multipath_del - other
locations that use rtnh_ok and then nla_get_u16 on RTA_ENCAP_TYPE
attribute.

Fixes: 9ed59592e3e3 ("lwtunnel: fix autoload of lwt modules")
Signed-off-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/core/lwtunnel.c
net/ipv4/fib_semantics.c
net/ipv6/route.c

index 8ec7d13d28608b773b54aa6c3a6729f8eaf1fc3f..f590b0e672a9b1760497991e490b6471984af0a8 100644 (file)
@@ -192,6 +192,10 @@ int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int remaining,
                        nla_entype = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
 
                        if (nla_entype) {
+                               if (nla_len(nla_entype) < sizeof(u16)) {
+                                       NL_SET_ERR_MSG(extack, "Invalid RTA_ENCAP_TYPE");
+                                       return -EINVAL;
+                               }
                                encap_type = nla_get_u16(nla_entype);
 
                                if (lwtunnel_valid_encap_type(encap_type,
index 72782843d575a088cd86018f0f2666e853c7b950..ab6a8f35d369ddd948992b83d1ebf9d88ba2b4cb 100644 (file)
@@ -741,6 +741,9 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
                        }
 
                        fib_cfg.fc_encap = nla_find(attrs, attrlen, RTA_ENCAP);
+                       /* RTA_ENCAP_TYPE length checked in
+                        * lwtunnel_valid_encap_type_attr
+                        */
                        nla = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
                        if (nla)
                                fib_cfg.fc_encap_type = nla_get_u16(nla);
index 25745bce2c1f3ee6e3e72d17c18072d4980028a4..7d10a4488b85dca1bffdc9823409fcbe6581d490 100644 (file)
@@ -5176,6 +5176,10 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
                                r_cfg.fc_flags |= RTF_GATEWAY;
                        }
                        r_cfg.fc_encap = nla_find(attrs, attrlen, RTA_ENCAP);
+
+                       /* RTA_ENCAP_TYPE length checked in
+                        * lwtunnel_valid_encap_type_attr
+                        */
                        nla = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
                        if (nla)
                                r_cfg.fc_encap_type = nla_get_u16(nla);