forked from Minki/linux
rtnetlink: stats: validate attributes in get as well as dumps
Make sure NETLINK_GET_STRICT_CHK influences both GETSTATS doit as well as the dump. Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
59c28058fa
commit
51bc860d4a
@ -4902,6 +4902,36 @@ static size_t if_nlmsg_stats_size(const struct net_device *dev,
|
||||
return size;
|
||||
}
|
||||
|
||||
static int rtnl_valid_stats_req(const struct nlmsghdr *nlh, bool strict_check,
|
||||
bool is_dump, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct if_stats_msg *ifsm;
|
||||
|
||||
if (nlh->nlmsg_len < sizeof(*ifsm)) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid header for stats dump");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!strict_check)
|
||||
return 0;
|
||||
|
||||
ifsm = nlmsg_data(nlh);
|
||||
|
||||
/* only requests using strict checks can pass data to influence
|
||||
* the dump. The legacy exception is filter_mask.
|
||||
*/
|
||||
if (ifsm->pad1 || ifsm->pad2 || (is_dump && ifsm->ifindex)) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid values in header for stats dump request");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (nlmsg_attrlen(nlh, sizeof(*ifsm))) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid attributes after stats header");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
@ -4913,8 +4943,10 @@ static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh,
|
||||
u32 filter_mask;
|
||||
int err;
|
||||
|
||||
if (nlmsg_len(nlh) < sizeof(*ifsm))
|
||||
return -EINVAL;
|
||||
err = rtnl_valid_stats_req(nlh, netlink_strict_get_check(skb),
|
||||
false, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ifsm = nlmsg_data(nlh);
|
||||
if (ifsm->ifindex > 0)
|
||||
@ -4966,27 +4998,11 @@ static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
|
||||
cb->seq = net->dev_base_seq;
|
||||
|
||||
if (nlmsg_len(cb->nlh) < sizeof(*ifsm)) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid header for stats dump");
|
||||
return -EINVAL;
|
||||
}
|
||||
err = rtnl_valid_stats_req(cb->nlh, cb->strict_check, true, extack);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
ifsm = nlmsg_data(cb->nlh);
|
||||
|
||||
/* only requests using strict checks can pass data to influence
|
||||
* the dump. The legacy exception is filter_mask.
|
||||
*/
|
||||
if (cb->strict_check) {
|
||||
if (ifsm->pad1 || ifsm->pad2 || ifsm->ifindex) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid values in header for stats dump request");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (nlmsg_attrlen(cb->nlh, sizeof(*ifsm))) {
|
||||
NL_SET_ERR_MSG(extack, "Invalid attributes after stats header");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
filter_mask = ifsm->filter_mask;
|
||||
if (!filter_mask) {
|
||||
NL_SET_ERR_MSG(extack, "Filter mask must be set for stats dump");
|
||||
|
Loading…
Reference in New Issue
Block a user