Commit 89da780a authored by Xin Long's avatar Xin Long Committed by Jakub Kicinski

rtnetlink: move validate_linkmsg out of do_setlink

This patch moves validate_linkmsg() out of do_setlink() to its callers
and deletes the early validate_linkmsg() call in __rtnl_newlink(), so
that it will not call validate_linkmsg() twice in either of the paths:

  - __rtnl_newlink() -> do_setlink()
  - __rtnl_newlink() -> rtnl_newlink_create() -> rtnl_create_link()

Additionally, as validate_linkmsg() is now only called with a real
dev, we can remove the NULL check for dev in validate_linkmsg().

Note that we moved validate_linkmsg() check to the places where it has
not done any changes to the dev, as Jakub suggested.
Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Link: https://lore.kernel.org/r/cf2ef061e08251faf9e8be25ff0d61150c030475.1686585334.git.lucien.xin@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent fa0e21fa
...@@ -2383,45 +2383,43 @@ static int rtnl_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate, ...@@ -2383,45 +2383,43 @@ static int rtnl_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[], static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[],
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
if (dev) { if (tb[IFLA_ADDRESS] &&
if (tb[IFLA_ADDRESS] && nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
nla_len(tb[IFLA_ADDRESS]) < dev->addr_len) return -EINVAL;
return -EINVAL;
if (tb[IFLA_BROADCAST] && if (tb[IFLA_BROADCAST] &&
nla_len(tb[IFLA_BROADCAST]) < dev->addr_len) nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
return -EINVAL; return -EINVAL;
if (tb[IFLA_GSO_MAX_SIZE] && if (tb[IFLA_GSO_MAX_SIZE] &&
nla_get_u32(tb[IFLA_GSO_MAX_SIZE]) > dev->tso_max_size) { nla_get_u32(tb[IFLA_GSO_MAX_SIZE]) > dev->tso_max_size) {
NL_SET_ERR_MSG(extack, "too big gso_max_size"); NL_SET_ERR_MSG(extack, "too big gso_max_size");
return -EINVAL; return -EINVAL;
} }
if (tb[IFLA_GSO_MAX_SEGS] && if (tb[IFLA_GSO_MAX_SEGS] &&
(nla_get_u32(tb[IFLA_GSO_MAX_SEGS]) > GSO_MAX_SEGS || (nla_get_u32(tb[IFLA_GSO_MAX_SEGS]) > GSO_MAX_SEGS ||
nla_get_u32(tb[IFLA_GSO_MAX_SEGS]) > dev->tso_max_segs)) { nla_get_u32(tb[IFLA_GSO_MAX_SEGS]) > dev->tso_max_segs)) {
NL_SET_ERR_MSG(extack, "too big gso_max_segs"); NL_SET_ERR_MSG(extack, "too big gso_max_segs");
return -EINVAL; return -EINVAL;
} }
if (tb[IFLA_GRO_MAX_SIZE] && if (tb[IFLA_GRO_MAX_SIZE] &&
nla_get_u32(tb[IFLA_GRO_MAX_SIZE]) > GRO_MAX_SIZE) { nla_get_u32(tb[IFLA_GRO_MAX_SIZE]) > GRO_MAX_SIZE) {
NL_SET_ERR_MSG(extack, "too big gro_max_size"); NL_SET_ERR_MSG(extack, "too big gro_max_size");
return -EINVAL; return -EINVAL;
} }
if (tb[IFLA_GSO_IPV4_MAX_SIZE] && if (tb[IFLA_GSO_IPV4_MAX_SIZE] &&
nla_get_u32(tb[IFLA_GSO_IPV4_MAX_SIZE]) > dev->tso_max_size) { nla_get_u32(tb[IFLA_GSO_IPV4_MAX_SIZE]) > dev->tso_max_size) {
NL_SET_ERR_MSG(extack, "too big gso_ipv4_max_size"); NL_SET_ERR_MSG(extack, "too big gso_ipv4_max_size");
return -EINVAL; return -EINVAL;
} }
if (tb[IFLA_GRO_IPV4_MAX_SIZE] && if (tb[IFLA_GRO_IPV4_MAX_SIZE] &&
nla_get_u32(tb[IFLA_GRO_IPV4_MAX_SIZE]) > GRO_MAX_SIZE) { nla_get_u32(tb[IFLA_GRO_IPV4_MAX_SIZE]) > GRO_MAX_SIZE) {
NL_SET_ERR_MSG(extack, "too big gro_ipv4_max_size"); NL_SET_ERR_MSG(extack, "too big gro_ipv4_max_size");
return -EINVAL; return -EINVAL;
}
} }
if (tb[IFLA_AF_SPEC]) { if (tb[IFLA_AF_SPEC]) {
...@@ -2742,10 +2740,6 @@ static int do_setlink(const struct sk_buff *skb, ...@@ -2742,10 +2740,6 @@ static int do_setlink(const struct sk_buff *skb,
char ifname[IFNAMSIZ]; char ifname[IFNAMSIZ];
int err; int err;
err = validate_linkmsg(dev, tb, extack);
if (err < 0)
return err;
if (tb[IFLA_IFNAME]) if (tb[IFLA_IFNAME])
nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
else else
...@@ -3162,6 +3156,10 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -3162,6 +3156,10 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
goto errout; goto errout;
} }
err = validate_linkmsg(dev, tb, extack);
if (err < 0)
goto errout;
err = do_setlink(skb, dev, ifm, extack, tb, 0); err = do_setlink(skb, dev, ifm, extack, tb, 0);
errout: errout:
return err; return err;
...@@ -3405,6 +3403,9 @@ static int rtnl_group_changelink(const struct sk_buff *skb, ...@@ -3405,6 +3403,9 @@ static int rtnl_group_changelink(const struct sk_buff *skb,
for_each_netdev_safe(net, dev, aux) { for_each_netdev_safe(net, dev, aux) {
if (dev->group == group) { if (dev->group == group) {
err = validate_linkmsg(dev, tb, extack);
if (err < 0)
return err;
err = do_setlink(skb, dev, ifm, extack, tb, 0); err = do_setlink(skb, dev, ifm, extack, tb, 0);
if (err < 0) if (err < 0)
return err; return err;
...@@ -3562,10 +3563,6 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -3562,10 +3563,6 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
m_ops = master_dev->rtnl_link_ops; m_ops = master_dev->rtnl_link_ops;
} }
err = validate_linkmsg(dev, tb, extack);
if (err < 0)
return err;
if (tb[IFLA_LINKINFO]) { if (tb[IFLA_LINKINFO]) {
err = nla_parse_nested_deprecated(linkinfo, IFLA_INFO_MAX, err = nla_parse_nested_deprecated(linkinfo, IFLA_INFO_MAX,
tb[IFLA_LINKINFO], tb[IFLA_LINKINFO],
...@@ -3629,6 +3626,10 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, ...@@ -3629,6 +3626,10 @@ static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh,
if (nlh->nlmsg_flags & NLM_F_REPLACE) if (nlh->nlmsg_flags & NLM_F_REPLACE)
return -EOPNOTSUPP; return -EOPNOTSUPP;
err = validate_linkmsg(dev, tb, extack);
if (err < 0)
return err;
if (linkinfo[IFLA_INFO_DATA]) { if (linkinfo[IFLA_INFO_DATA]) {
if (!ops || ops != dev->rtnl_link_ops || if (!ops || ops != dev->rtnl_link_ops ||
!ops->changelink) !ops->changelink)
......
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