Skip to content

Commit 4760aba

Browse files
committed
Merge branch 'mpr-len-checks'
David Ahern says: ==================== net: Length checks for attributes within multipath routes Add length checks for attributes within a multipath route (attributes within RTA_MULTIPATH). Motivated by the syzbot report in patch 1 and then expanded to other attributes as noted by Ido. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 74c78b4 + 8bda81a commit 4760aba

File tree

3 files changed

+76
-8
lines changed

3 files changed

+76
-8
lines changed

net/core/lwtunnel.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,10 @@ int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int remaining,
197197
nla_entype = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
198198

199199
if (nla_entype) {
200+
if (nla_len(nla_entype) < sizeof(u16)) {
201+
NL_SET_ERR_MSG(extack, "Invalid RTA_ENCAP_TYPE");
202+
return -EINVAL;
203+
}
200204
encap_type = nla_get_u16(nla_entype);
201205

202206
if (lwtunnel_valid_encap_type(encap_type,

net/ipv4/fib_semantics.c

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,19 @@ static int fib_count_nexthops(struct rtnexthop *rtnh, int remaining,
662662
return nhs;
663663
}
664664

665+
static int fib_gw_from_attr(__be32 *gw, struct nlattr *nla,
666+
struct netlink_ext_ack *extack)
667+
{
668+
if (nla_len(nla) < sizeof(*gw)) {
669+
NL_SET_ERR_MSG(extack, "Invalid IPv4 address in RTA_GATEWAY");
670+
return -EINVAL;
671+
}
672+
673+
*gw = nla_get_in_addr(nla);
674+
675+
return 0;
676+
}
677+
665678
/* only called when fib_nh is integrated into fib_info */
666679
static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
667680
int remaining, struct fib_config *cfg,
@@ -704,7 +717,11 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
704717
return -EINVAL;
705718
}
706719
if (nla) {
707-
fib_cfg.fc_gw4 = nla_get_in_addr(nla);
720+
ret = fib_gw_from_attr(&fib_cfg.fc_gw4, nla,
721+
extack);
722+
if (ret)
723+
goto errout;
724+
708725
if (fib_cfg.fc_gw4)
709726
fib_cfg.fc_gw_family = AF_INET;
710727
} else if (nlav) {
@@ -714,10 +731,18 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
714731
}
715732

716733
nla = nla_find(attrs, attrlen, RTA_FLOW);
717-
if (nla)
734+
if (nla) {
735+
if (nla_len(nla) < sizeof(u32)) {
736+
NL_SET_ERR_MSG(extack, "Invalid RTA_FLOW");
737+
return -EINVAL;
738+
}
718739
fib_cfg.fc_flow = nla_get_u32(nla);
740+
}
719741

720742
fib_cfg.fc_encap = nla_find(attrs, attrlen, RTA_ENCAP);
743+
/* RTA_ENCAP_TYPE length checked in
744+
* lwtunnel_valid_encap_type_attr
745+
*/
721746
nla = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
722747
if (nla)
723748
fib_cfg.fc_encap_type = nla_get_u16(nla);
@@ -902,6 +927,7 @@ int fib_nh_match(struct net *net, struct fib_config *cfg, struct fib_info *fi,
902927
attrlen = rtnh_attrlen(rtnh);
903928
if (attrlen > 0) {
904929
struct nlattr *nla, *nlav, *attrs = rtnh_attrs(rtnh);
930+
int err;
905931

906932
nla = nla_find(attrs, attrlen, RTA_GATEWAY);
907933
nlav = nla_find(attrs, attrlen, RTA_VIA);
@@ -912,12 +938,17 @@ int fib_nh_match(struct net *net, struct fib_config *cfg, struct fib_info *fi,
912938
}
913939

914940
if (nla) {
941+
__be32 gw;
942+
943+
err = fib_gw_from_attr(&gw, nla, extack);
944+
if (err)
945+
return err;
946+
915947
if (nh->fib_nh_gw_family != AF_INET ||
916-
nla_get_in_addr(nla) != nh->fib_nh_gw4)
948+
gw != nh->fib_nh_gw4)
917949
return 1;
918950
} else if (nlav) {
919951
struct fib_config cfg2;
920-
int err;
921952

922953
err = fib_gw_from_via(&cfg2, nlav, extack);
923954
if (err)
@@ -940,8 +971,14 @@ int fib_nh_match(struct net *net, struct fib_config *cfg, struct fib_info *fi,
940971

941972
#ifdef CONFIG_IP_ROUTE_CLASSID
942973
nla = nla_find(attrs, attrlen, RTA_FLOW);
943-
if (nla && nla_get_u32(nla) != nh->nh_tclassid)
944-
return 1;
974+
if (nla) {
975+
if (nla_len(nla) < sizeof(u32)) {
976+
NL_SET_ERR_MSG(extack, "Invalid RTA_FLOW");
977+
return -EINVAL;
978+
}
979+
if (nla_get_u32(nla) != nh->nh_tclassid)
980+
return 1;
981+
}
945982
#endif
946983
}
947984

net/ipv6/route.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5224,6 +5224,19 @@ static bool ip6_route_mpath_should_notify(const struct fib6_info *rt)
52245224
return should_notify;
52255225
}
52265226

5227+
static int fib6_gw_from_attr(struct in6_addr *gw, struct nlattr *nla,
5228+
struct netlink_ext_ack *extack)
5229+
{
5230+
if (nla_len(nla) < sizeof(*gw)) {
5231+
NL_SET_ERR_MSG(extack, "Invalid IPv6 address in RTA_GATEWAY");
5232+
return -EINVAL;
5233+
}
5234+
5235+
*gw = nla_get_in6_addr(nla);
5236+
5237+
return 0;
5238+
}
5239+
52275240
static int ip6_route_multipath_add(struct fib6_config *cfg,
52285241
struct netlink_ext_ack *extack)
52295242
{
@@ -5264,10 +5277,20 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
52645277

52655278
nla = nla_find(attrs, attrlen, RTA_GATEWAY);
52665279
if (nla) {
5267-
r_cfg.fc_gateway = nla_get_in6_addr(nla);
5280+
int ret;
5281+
5282+
ret = fib6_gw_from_attr(&r_cfg.fc_gateway, nla,
5283+
extack);
5284+
if (ret)
5285+
return ret;
5286+
52685287
r_cfg.fc_flags |= RTF_GATEWAY;
52695288
}
52705289
r_cfg.fc_encap = nla_find(attrs, attrlen, RTA_ENCAP);
5290+
5291+
/* RTA_ENCAP_TYPE length checked in
5292+
* lwtunnel_valid_encap_type_attr
5293+
*/
52715294
nla = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
52725295
if (nla)
52735296
r_cfg.fc_encap_type = nla_get_u16(nla);
@@ -5434,7 +5457,11 @@ static int ip6_route_multipath_del(struct fib6_config *cfg,
54345457

54355458
nla = nla_find(attrs, attrlen, RTA_GATEWAY);
54365459
if (nla) {
5437-
nla_memcpy(&r_cfg.fc_gateway, nla, 16);
5460+
err = fib6_gw_from_attr(&r_cfg.fc_gateway, nla,
5461+
extack);
5462+
if (err)
5463+
return err;
5464+
54385465
r_cfg.fc_flags |= RTF_GATEWAY;
54395466
}
54405467
}

0 commit comments

Comments
 (0)