Skip to content

Commit 3021dbf

Browse files
committed
Merge branch 'rtnetlink-a-couple-of-fixes-in-linkmsg-validation'
Xin Long says: ==================== rtnetlink: a couple of fixes in linkmsg validation validate_linkmsg() was introduced to do linkmsg validation for existing links. However, the new created links also need this linkmsg validation. Add validate_linkmsg() check for link creating in Patch 1, and add more tb checks into validate_linkmsg() in Patch 2 and 3. ==================== Link: https://lore.kernel.org/r/cover.1685548598.git.lucien.xin@gmail.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2 parents abaf8d5 + 65d6914 commit 3021dbf

1 file changed

Lines changed: 38 additions & 16 deletions

File tree

net/core/rtnetlink.c

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2385,6 +2385,37 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[],
23852385
if (tb[IFLA_BROADCAST] &&
23862386
nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
23872387
return -EINVAL;
2388+
2389+
if (tb[IFLA_GSO_MAX_SIZE] &&
2390+
nla_get_u32(tb[IFLA_GSO_MAX_SIZE]) > dev->tso_max_size) {
2391+
NL_SET_ERR_MSG(extack, "too big gso_max_size");
2392+
return -EINVAL;
2393+
}
2394+
2395+
if (tb[IFLA_GSO_MAX_SEGS] &&
2396+
(nla_get_u32(tb[IFLA_GSO_MAX_SEGS]) > GSO_MAX_SEGS ||
2397+
nla_get_u32(tb[IFLA_GSO_MAX_SEGS]) > dev->tso_max_segs)) {
2398+
NL_SET_ERR_MSG(extack, "too big gso_max_segs");
2399+
return -EINVAL;
2400+
}
2401+
2402+
if (tb[IFLA_GRO_MAX_SIZE] &&
2403+
nla_get_u32(tb[IFLA_GRO_MAX_SIZE]) > GRO_MAX_SIZE) {
2404+
NL_SET_ERR_MSG(extack, "too big gro_max_size");
2405+
return -EINVAL;
2406+
}
2407+
2408+
if (tb[IFLA_GSO_IPV4_MAX_SIZE] &&
2409+
nla_get_u32(tb[IFLA_GSO_IPV4_MAX_SIZE]) > dev->tso_max_size) {
2410+
NL_SET_ERR_MSG(extack, "too big gso_ipv4_max_size");
2411+
return -EINVAL;
2412+
}
2413+
2414+
if (tb[IFLA_GRO_IPV4_MAX_SIZE] &&
2415+
nla_get_u32(tb[IFLA_GRO_IPV4_MAX_SIZE]) > GRO_MAX_SIZE) {
2416+
NL_SET_ERR_MSG(extack, "too big gro_ipv4_max_size");
2417+
return -EINVAL;
2418+
}
23882419
}
23892420

23902421
if (tb[IFLA_AF_SPEC]) {
@@ -2858,11 +2889,6 @@ static int do_setlink(const struct sk_buff *skb,
28582889
if (tb[IFLA_GSO_MAX_SIZE]) {
28592890
u32 max_size = nla_get_u32(tb[IFLA_GSO_MAX_SIZE]);
28602891

2861-
if (max_size > dev->tso_max_size) {
2862-
err = -EINVAL;
2863-
goto errout;
2864-
}
2865-
28662892
if (dev->gso_max_size ^ max_size) {
28672893
netif_set_gso_max_size(dev, max_size);
28682894
status |= DO_SETLINK_MODIFIED;
@@ -2872,11 +2898,6 @@ static int do_setlink(const struct sk_buff *skb,
28722898
if (tb[IFLA_GSO_MAX_SEGS]) {
28732899
u32 max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]);
28742900

2875-
if (max_segs > GSO_MAX_SEGS || max_segs > dev->tso_max_segs) {
2876-
err = -EINVAL;
2877-
goto errout;
2878-
}
2879-
28802901
if (dev->gso_max_segs ^ max_segs) {
28812902
netif_set_gso_max_segs(dev, max_segs);
28822903
status |= DO_SETLINK_MODIFIED;
@@ -2895,11 +2916,6 @@ static int do_setlink(const struct sk_buff *skb,
28952916
if (tb[IFLA_GSO_IPV4_MAX_SIZE]) {
28962917
u32 max_size = nla_get_u32(tb[IFLA_GSO_IPV4_MAX_SIZE]);
28972918

2898-
if (max_size > dev->tso_max_size) {
2899-
err = -EINVAL;
2900-
goto errout;
2901-
}
2902-
29032919
if (dev->gso_ipv4_max_size ^ max_size) {
29042920
netif_set_gso_ipv4_max_size(dev, max_size);
29052921
status |= DO_SETLINK_MODIFIED;
@@ -3285,6 +3301,7 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
32853301
struct net_device *dev;
32863302
unsigned int num_tx_queues = 1;
32873303
unsigned int num_rx_queues = 1;
3304+
int err;
32883305

32893306
if (tb[IFLA_NUM_TX_QUEUES])
32903307
num_tx_queues = nla_get_u32(tb[IFLA_NUM_TX_QUEUES]);
@@ -3320,13 +3337,18 @@ struct net_device *rtnl_create_link(struct net *net, const char *ifname,
33203337
if (!dev)
33213338
return ERR_PTR(-ENOMEM);
33223339

3340+
err = validate_linkmsg(dev, tb, extack);
3341+
if (err < 0) {
3342+
free_netdev(dev);
3343+
return ERR_PTR(err);
3344+
}
3345+
33233346
dev_net_set(dev, net);
33243347
dev->rtnl_link_ops = ops;
33253348
dev->rtnl_link_state = RTNL_LINK_INITIALIZING;
33263349

33273350
if (tb[IFLA_MTU]) {
33283351
u32 mtu = nla_get_u32(tb[IFLA_MTU]);
3329-
int err;
33303352

33313353
err = dev_validate_mtu(dev, mtu, extack);
33323354
if (err) {

0 commit comments

Comments
 (0)