Commit d0440029 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by David S. Miller

net: ipv4: ipmr: perform strict checks also for doit handlers

Make RTM_GETROUTE's doit handler use strict checks when
NETLINK_F_STRICT_CHK is set.

v2: - improve extack messages (DaveA).
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent a00302b6
...@@ -2467,6 +2467,61 @@ static void igmpmsg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt) ...@@ -2467,6 +2467,61 @@ static void igmpmsg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt)
rtnl_set_sk_err(net, RTNLGRP_IPV4_MROUTE_R, -ENOBUFS); rtnl_set_sk_err(net, RTNLGRP_IPV4_MROUTE_R, -ENOBUFS);
} }
static int ipmr_rtm_valid_getroute_req(struct sk_buff *skb,
const struct nlmsghdr *nlh,
struct nlattr **tb,
struct netlink_ext_ack *extack)
{
struct rtmsg *rtm;
int i, err;
if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*rtm))) {
NL_SET_ERR_MSG(extack, "ipv4: Invalid header for multicast route get request");
return -EINVAL;
}
if (!netlink_strict_get_check(skb))
return nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX,
rtm_ipv4_policy, extack);
rtm = nlmsg_data(nlh);
if ((rtm->rtm_src_len && rtm->rtm_src_len != 32) ||
(rtm->rtm_dst_len && rtm->rtm_dst_len != 32) ||
rtm->rtm_tos || rtm->rtm_table || rtm->rtm_protocol ||
rtm->rtm_scope || rtm->rtm_type || rtm->rtm_flags) {
NL_SET_ERR_MSG(extack, "ipv4: Invalid values in header for multicast route get request");
return -EINVAL;
}
err = nlmsg_parse_strict(nlh, sizeof(*rtm), tb, RTA_MAX,
rtm_ipv4_policy, extack);
if (err)
return err;
if ((tb[RTA_SRC] && !rtm->rtm_src_len) ||
(tb[RTA_DST] && !rtm->rtm_dst_len)) {
NL_SET_ERR_MSG(extack, "ipv4: rtm_src_len and rtm_dst_len must be 32 for IPv4");
return -EINVAL;
}
for (i = 0; i <= RTA_MAX; i++) {
if (!tb[i])
continue;
switch (i) {
case RTA_SRC:
case RTA_DST:
case RTA_TABLE:
break;
default:
NL_SET_ERR_MSG(extack, "ipv4: Unsupported attribute in multicast route get request");
return -EINVAL;
}
}
return 0;
}
static int ipmr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, static int ipmr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
...@@ -2475,18 +2530,14 @@ static int ipmr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, ...@@ -2475,18 +2530,14 @@ static int ipmr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
struct sk_buff *skb = NULL; struct sk_buff *skb = NULL;
struct mfc_cache *cache; struct mfc_cache *cache;
struct mr_table *mrt; struct mr_table *mrt;
struct rtmsg *rtm;
__be32 src, grp; __be32 src, grp;
u32 tableid; u32 tableid;
int err; int err;
err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, err = ipmr_rtm_valid_getroute_req(in_skb, nlh, tb, extack);
rtm_ipv4_policy, extack);
if (err < 0) if (err < 0)
goto errout; goto errout;
rtm = nlmsg_data(nlh);
src = tb[RTA_SRC] ? nla_get_in_addr(tb[RTA_SRC]) : 0; src = tb[RTA_SRC] ? nla_get_in_addr(tb[RTA_SRC]) : 0;
grp = tb[RTA_DST] ? nla_get_in_addr(tb[RTA_DST]) : 0; grp = tb[RTA_DST] ? nla_get_in_addr(tb[RTA_DST]) : 0;
tableid = tb[RTA_TABLE] ? nla_get_u32(tb[RTA_TABLE]) : 0; tableid = tb[RTA_TABLE] ? nla_get_u32(tb[RTA_TABLE]) : 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment