aboutsummaryrefslogtreecommitdiffstats
path: root/net/mpls/af_mpls.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2019-04-26 08:07:28 -0400
committerDavid S. Miller <davem@davemloft.net>2019-04-27 17:07:21 -0400
commit8cb081746c031fb164089322e2336a0bf5b3070c (patch)
tree1404b16c0859f9d67e67247a10833050c870a3cf /net/mpls/af_mpls.c
parent6f455f5f4e9c28aefaefbe18ce7304b499645d75 (diff)
netlink: make validation more configurable for future strictness
We currently have two levels of strict validation: 1) liberal (default) - undefined (type >= max) & NLA_UNSPEC attributes accepted - attribute length >= expected accepted - garbage at end of message accepted 2) strict (opt-in) - NLA_UNSPEC attributes accepted - attribute length >= expected accepted Split out parsing strictness into four different options: * TRAILING - check that there's no trailing data after parsing attributes (in message or nested) * MAXTYPE - reject attrs > max known type * UNSPEC - reject attributes with NLA_UNSPEC policy entries * STRICT_ATTRS - strictly validate attribute size The default for future things should be *everything*. The current *_strict() is a combination of TRAILING and MAXTYPE, and is renamed to _deprecated_strict(). The current regular parsing has none of this, and is renamed to *_parse_deprecated(). Additionally it allows us to selectively set one of the new flags even on old policies. Notably, the UNSPEC flag could be useful in this case, since it can be arranged (by filling in the policy) to not be an incompatible userspace ABI change, but would then going forward prevent forgetting attribute entries. Similar can apply to the POLICY flag. We end up with the following renames: * nla_parse -> nla_parse_deprecated * nla_parse_strict -> nla_parse_deprecated_strict * nlmsg_parse -> nlmsg_parse_deprecated * nlmsg_parse_strict -> nlmsg_parse_deprecated_strict * nla_parse_nested -> nla_parse_nested_deprecated * nla_validate_nested -> nla_validate_nested_deprecated Using spatch, of course: @@ expression TB, MAX, HEAD, LEN, POL, EXT; @@ -nla_parse(TB, MAX, HEAD, LEN, POL, EXT) +nla_parse_deprecated(TB, MAX, HEAD, LEN, POL, EXT) @@ expression NLH, HDRLEN, TB, MAX, POL, EXT; @@ -nlmsg_parse(NLH, HDRLEN, TB, MAX, POL, EXT) +nlmsg_parse_deprecated(NLH, HDRLEN, TB, MAX, POL, EXT) @@ expression NLH, HDRLEN, TB, MAX, POL, EXT; @@ -nlmsg_parse_strict(NLH, HDRLEN, TB, MAX, POL, EXT) +nlmsg_parse_deprecated_strict(NLH, HDRLEN, TB, MAX, POL, EXT) @@ expression TB, MAX, NLA, POL, EXT; @@ -nla_parse_nested(TB, MAX, NLA, POL, EXT) +nla_parse_nested_deprecated(TB, MAX, NLA, POL, EXT) @@ expression START, MAX, POL, EXT; @@ -nla_validate_nested(START, MAX, POL, EXT) +nla_validate_nested_deprecated(START, MAX, POL, EXT) @@ expression NLH, HDRLEN, MAX, POL, EXT; @@ -nlmsg_validate(NLH, HDRLEN, MAX, POL, EXT) +nlmsg_validate_deprecated(NLH, HDRLEN, MAX, POL, EXT) For this patch, don't actually add the strict, non-renamed versions yet so that it breaks compile if I get it wrong. Also, while at it, make nla_validate and nla_parse go down to a common __nla_validate_parse() function to avoid code duplication. Ultimately, this allows us to have very strict validation for every new caller of nla_parse()/nlmsg_parse() etc as re-introduced in the next patch, while existing things will continue to work as is. In effect then, this adds fully strict validation for any new command. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mpls/af_mpls.c')
-rw-r--r--net/mpls/af_mpls.c26
1 files changed, 14 insertions, 12 deletions
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 01f8a4f97872..baa098291fb0 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -1223,11 +1223,13 @@ static int mpls_netconf_valid_get_req(struct sk_buff *skb,
1223 } 1223 }
1224 1224
1225 if (!netlink_strict_get_check(skb)) 1225 if (!netlink_strict_get_check(skb))
1226 return nlmsg_parse(nlh, sizeof(struct netconfmsg), tb, 1226 return nlmsg_parse_deprecated(nlh, sizeof(struct netconfmsg),
1227 NETCONFA_MAX, devconf_mpls_policy, extack); 1227 tb, NETCONFA_MAX,
1228 devconf_mpls_policy, extack);
1228 1229
1229 err = nlmsg_parse_strict(nlh, sizeof(struct netconfmsg), tb, 1230 err = nlmsg_parse_deprecated_strict(nlh, sizeof(struct netconfmsg),
1230 NETCONFA_MAX, devconf_mpls_policy, extack); 1231 tb, NETCONFA_MAX,
1232 devconf_mpls_policy, extack);
1231 if (err) 1233 if (err)
1232 return err; 1234 return err;
1233 1235
@@ -1788,8 +1790,8 @@ static int rtm_to_route_config(struct sk_buff *skb,
1788 int index; 1790 int index;
1789 int err; 1791 int err;
1790 1792
1791 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_mpls_policy, 1793 err = nlmsg_parse_deprecated(nlh, sizeof(*rtm), tb, RTA_MAX,
1792 extack); 1794 rtm_mpls_policy, extack);
1793 if (err < 0) 1795 if (err < 0)
1794 goto errout; 1796 goto errout;
1795 1797
@@ -2106,8 +2108,8 @@ static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
2106 cb->answer_flags = NLM_F_DUMP_FILTERED; 2108 cb->answer_flags = NLM_F_DUMP_FILTERED;
2107 } 2109 }
2108 2110
2109 err = nlmsg_parse_strict(nlh, sizeof(*rtm), tb, RTA_MAX, 2111 err = nlmsg_parse_deprecated_strict(nlh, sizeof(*rtm), tb, RTA_MAX,
2110 rtm_mpls_policy, extack); 2112 rtm_mpls_policy, extack);
2111 if (err < 0) 2113 if (err < 0)
2112 return err; 2114 return err;
2113 2115
@@ -2290,8 +2292,8 @@ static int mpls_valid_getroute_req(struct sk_buff *skb,
2290 } 2292 }
2291 2293
2292 if (!netlink_strict_get_check(skb)) 2294 if (!netlink_strict_get_check(skb))
2293 return nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, 2295 return nlmsg_parse_deprecated(nlh, sizeof(*rtm), tb, RTA_MAX,
2294 rtm_mpls_policy, extack); 2296 rtm_mpls_policy, extack);
2295 2297
2296 rtm = nlmsg_data(nlh); 2298 rtm = nlmsg_data(nlh);
2297 if ((rtm->rtm_dst_len && rtm->rtm_dst_len != 20) || 2299 if ((rtm->rtm_dst_len && rtm->rtm_dst_len != 20) ||
@@ -2306,8 +2308,8 @@ static int mpls_valid_getroute_req(struct sk_buff *skb,
2306 return -EINVAL; 2308 return -EINVAL;
2307 } 2309 }
2308 2310
2309 err = nlmsg_parse_strict(nlh, sizeof(*rtm), tb, RTA_MAX, 2311 err = nlmsg_parse_deprecated_strict(nlh, sizeof(*rtm), tb, RTA_MAX,
2310 rtm_mpls_policy, extack); 2312 rtm_mpls_policy, extack);
2311 if (err) 2313 if (err)
2312 return err; 2314 return err;
2313 2315