Skip to content

Commit 51bc860

Browse files
Jakub Kicinskidavem330
Jakub Kicinski
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 59c2805 commit 51bc860

File tree

1 file changed

+37
-21
lines changed

1 file changed

+37
-21
lines changed

net/core/rtnetlink.c

+37-21
Original file line numberDiff line numberDiff line change
@@ -4902,6 +4902,36 @@ static size_t if_nlmsg_stats_size(const struct net_device *dev,
49024902
return size;
49034903
}
49044904

4905+
static int rtnl_valid_stats_req(const struct nlmsghdr *nlh, bool strict_check,
4906+
bool is_dump, struct netlink_ext_ack *extack)
4907+
{
4908+
struct if_stats_msg *ifsm;
4909+
4910+
if (nlh->nlmsg_len < sizeof(*ifsm)) {
4911+
NL_SET_ERR_MSG(extack, "Invalid header for stats dump");
4912+
return -EINVAL;
4913+
}
4914+
4915+
if (!strict_check)
4916+
return 0;
4917+
4918+
ifsm = nlmsg_data(nlh);
4919+
4920+
/* only requests using strict checks can pass data to influence
4921+
* the dump. The legacy exception is filter_mask.
4922+
*/
4923+
if (ifsm->pad1 || ifsm->pad2 || (is_dump && ifsm->ifindex)) {
4924+
NL_SET_ERR_MSG(extack, "Invalid values in header for stats dump request");
4925+
return -EINVAL;
4926+
}
4927+
if (nlmsg_attrlen(nlh, sizeof(*ifsm))) {
4928+
NL_SET_ERR_MSG(extack, "Invalid attributes after stats header");
4929+
return -EINVAL;
4930+
}
4931+
4932+
return 0;
4933+
}
4934+
49054935
static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh,
49064936
struct netlink_ext_ack *extack)
49074937
{
@@ -4913,8 +4943,10 @@ static int rtnl_stats_get(struct sk_buff *skb, struct nlmsghdr *nlh,
49134943
u32 filter_mask;
49144944
int err;
49154945

4916-
if (nlmsg_len(nlh) < sizeof(*ifsm))
4917-
return -EINVAL;
4946+
err = rtnl_valid_stats_req(nlh, netlink_strict_get_check(skb),
4947+
false, extack);
4948+
if (err)
4949+
return err;
49184950

49194951
ifsm = nlmsg_data(nlh);
49204952
if (ifsm->ifindex > 0)
@@ -4966,27 +4998,11 @@ static int rtnl_stats_dump(struct sk_buff *skb, struct netlink_callback *cb)
49664998

49674999
cb->seq = net->dev_base_seq;
49685000

4969-
if (nlmsg_len(cb->nlh) < sizeof(*ifsm)) {
4970-
NL_SET_ERR_MSG(extack, "Invalid header for stats dump");
4971-
return -EINVAL;
4972-
}
5001+
err = rtnl_valid_stats_req(cb->nlh, cb->strict_check, true, extack);
5002+
if (err)
5003+
return err;
49735004

49745005
ifsm = nlmsg_data(cb->nlh);
4975-
4976-
/* only requests using strict checks can pass data to influence
4977-
* the dump. The legacy exception is filter_mask.
4978-
*/
4979-
if (cb->strict_check) {
4980-
if (ifsm->pad1 || ifsm->pad2 || ifsm->ifindex) {
4981-
NL_SET_ERR_MSG(extack, "Invalid values in header for stats dump request");
4982-
return -EINVAL;
4983-
}
4984-
if (nlmsg_attrlen(cb->nlh, sizeof(*ifsm))) {
4985-
NL_SET_ERR_MSG(extack, "Invalid attributes after stats header");
4986-
return -EINVAL;
4987-
}
4988-
}
4989-
49905006
filter_mask = ifsm->filter_mask;
49915007
if (!filter_mask) {
49925008
NL_SET_ERR_MSG(extack, "Filter mask must be set for stats dump");

0 commit comments

Comments
 (0)