From: David Ahern dsahern@kernel.org
stable inclusion from stable-v5.10.91 commit f403b5f96e9a153f00d1f3503b4e4dbb066601f8 bugzilla: 186187 https://gitee.com/openeuler/kernel/issues/I4SI2C
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
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 Signed-off-by: Chen Jun chenjun102@huawei.com Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com --- net/core/lwtunnel.c | 4 ++++ net/ipv4/fib_semantics.c | 3 +++ net/ipv6/route.c | 4 ++++ 3 files changed, 11 insertions(+)
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c index 8ec7d13d2860..f590b0e672a9 100644 --- a/net/core/lwtunnel.c +++ b/net/core/lwtunnel.c @@ -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, diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 72782843d575..ab6a8f35d369 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -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); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 25745bce2c1f..7d10a4488b85 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -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);