lwtunnel: Validate RTA_ENCAP_TYPE attribute length

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: 9ed59592e3 ("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>
This commit is contained in:
David Ahern 2021-12-30 17:36:35 -07:00 committed by Greg Kroah-Hartman
parent 48d5adb08d
commit f403b5f96e
3 changed files with 11 additions and 0 deletions

View 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); nla_entype = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
if (nla_entype) { 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); encap_type = nla_get_u16(nla_entype);
if (lwtunnel_valid_encap_type(encap_type, if (lwtunnel_valid_encap_type(encap_type,

View 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); 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); nla = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
if (nla) if (nla)
fib_cfg.fc_encap_type = nla_get_u16(nla); fib_cfg.fc_encap_type = nla_get_u16(nla);

View File

@ -5176,6 +5176,10 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
r_cfg.fc_flags |= RTF_GATEWAY; r_cfg.fc_flags |= RTF_GATEWAY;
} }
r_cfg.fc_encap = nla_find(attrs, attrlen, RTA_ENCAP); 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); nla = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
if (nla) if (nla)
r_cfg.fc_encap_type = nla_get_u16(nla); r_cfg.fc_encap_type = nla_get_u16(nla);