diff options
author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2019-01-18 13:46:25 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-01-19 13:09:59 -0500 |
commit | d77851bf68f48430a136af433783763ea7a35c3a (patch) | |
tree | 2bd151b30849e25dd634232d7ddc84da187336bd /net/mpls/af_mpls.c | |
parent | 0eff0a274104487938d741b5c37aca1795afd184 (diff) |
net: mpls: route: perform strict checks also for doit handlers
Make RTM_GETROUTE's doit handler use strict checks when
NETLINK_F_STRICT_CHK is set.
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.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.c | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 7d55d4c04088..733c86db551b 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
@@ -2236,6 +2236,64 @@ errout: | |||
2236 | rtnl_set_sk_err(net, RTNLGRP_MPLS_ROUTE, err); | 2236 | rtnl_set_sk_err(net, RTNLGRP_MPLS_ROUTE, err); |
2237 | } | 2237 | } |
2238 | 2238 | ||
2239 | static int mpls_valid_getroute_req(struct sk_buff *skb, | ||
2240 | const struct nlmsghdr *nlh, | ||
2241 | struct nlattr **tb, | ||
2242 | struct netlink_ext_ack *extack) | ||
2243 | { | ||
2244 | struct rtmsg *rtm; | ||
2245 | int i, err; | ||
2246 | |||
2247 | if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*rtm))) { | ||
2248 | NL_SET_ERR_MSG_MOD(extack, | ||
2249 | "Invalid header for get route request"); | ||
2250 | return -EINVAL; | ||
2251 | } | ||
2252 | |||
2253 | if (!netlink_strict_get_check(skb)) | ||
2254 | return nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, | ||
2255 | rtm_mpls_policy, extack); | ||
2256 | |||
2257 | rtm = nlmsg_data(nlh); | ||
2258 | if ((rtm->rtm_dst_len && rtm->rtm_dst_len != 20) || | ||
2259 | rtm->rtm_src_len || rtm->rtm_tos || rtm->rtm_table || | ||
2260 | rtm->rtm_protocol || rtm->rtm_scope || rtm->rtm_type) { | ||
2261 | NL_SET_ERR_MSG_MOD(extack, "Invalid values in header for get route request"); | ||
2262 | return -EINVAL; | ||
2263 | } | ||
2264 | if (rtm->rtm_flags & ~RTM_F_FIB_MATCH) { | ||
2265 | NL_SET_ERR_MSG_MOD(extack, | ||
2266 | "Invalid flags for get route request"); | ||
2267 | return -EINVAL; | ||
2268 | } | ||
2269 | |||
2270 | err = nlmsg_parse_strict(nlh, sizeof(*rtm), tb, RTA_MAX, | ||
2271 | rtm_mpls_policy, extack); | ||
2272 | if (err) | ||
2273 | return err; | ||
2274 | |||
2275 | if ((tb[RTA_DST] || tb[RTA_NEWDST]) && !rtm->rtm_dst_len) { | ||
2276 | NL_SET_ERR_MSG_MOD(extack, "rtm_dst_len must be 20 for MPLS"); | ||
2277 | return -EINVAL; | ||
2278 | } | ||
2279 | |||
2280 | for (i = 0; i <= RTA_MAX; i++) { | ||
2281 | if (!tb[i]) | ||
2282 | continue; | ||
2283 | |||
2284 | switch (i) { | ||
2285 | case RTA_DST: | ||
2286 | case RTA_NEWDST: | ||
2287 | break; | ||
2288 | default: | ||
2289 | NL_SET_ERR_MSG_MOD(extack, "Unsupported attribute in get route request"); | ||
2290 | return -EINVAL; | ||
2291 | } | ||
2292 | } | ||
2293 | |||
2294 | return 0; | ||
2295 | } | ||
2296 | |||
2239 | static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, | 2297 | static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, |
2240 | struct netlink_ext_ack *extack) | 2298 | struct netlink_ext_ack *extack) |
2241 | { | 2299 | { |
@@ -2255,8 +2313,7 @@ static int mpls_getroute(struct sk_buff *in_skb, struct nlmsghdr *in_nlh, | |||
2255 | u8 n_labels; | 2313 | u8 n_labels; |
2256 | int err; | 2314 | int err; |
2257 | 2315 | ||
2258 | err = nlmsg_parse(in_nlh, sizeof(*rtm), tb, RTA_MAX, | 2316 | err = mpls_valid_getroute_req(in_skb, in_nlh, tb, extack); |
2259 | rtm_mpls_policy, extack); | ||
2260 | if (err < 0) | 2317 | if (err < 0) |
2261 | goto errout; | 2318 | goto errout; |
2262 | 2319 | ||