@@ -2881,8 +2881,8 @@ static int do_set_proto_down(struct net_device *dev,
2881
2881
#define DO_SETLINK_MODIFIED 0x01
2882
2882
/* notify flag means notify + modified. */
2883
2883
#define DO_SETLINK_NOTIFY 0x03
2884
- static int do_setlink (const struct sk_buff * skb ,
2885
- struct net_device * dev , struct ifinfomsg * ifm ,
2884
+ static int do_setlink (const struct sk_buff * skb , struct net_device * dev ,
2885
+ struct net * tgt_net , struct ifinfomsg * ifm ,
2886
2886
struct netlink_ext_ack * extack ,
2887
2887
struct nlattr * * tb , int status )
2888
2888
{
@@ -2899,27 +2899,19 @@ static int do_setlink(const struct sk_buff *skb,
2899
2899
else
2900
2900
ifname [0 ] = '\0' ;
2901
2901
2902
- if (tb [ IFLA_NET_NS_PID ] || tb [ IFLA_NET_NS_FD ] || tb [ IFLA_TARGET_NETNSID ] ) {
2902
+ if (! net_eq ( tgt_net , dev_net ( dev )) ) {
2903
2903
const char * pat = ifname [0 ] ? ifname : NULL ;
2904
- struct net * net ;
2905
2904
int new_ifindex ;
2906
2905
2907
- net = rtnl_link_get_net_capable (skb , dev_net (dev ),
2908
- tb , CAP_NET_ADMIN );
2909
- if (IS_ERR (net )) {
2910
- err = PTR_ERR (net );
2911
- goto errout ;
2912
- }
2913
-
2914
2906
if (tb [IFLA_NEW_IFINDEX ])
2915
2907
new_ifindex = nla_get_s32 (tb [IFLA_NEW_IFINDEX ]);
2916
2908
else
2917
2909
new_ifindex = 0 ;
2918
2910
2919
- err = __dev_change_net_namespace (dev , net , pat , new_ifindex );
2920
- put_net (net );
2911
+ err = __dev_change_net_namespace (dev , tgt_net , pat , new_ifindex );
2921
2912
if (err )
2922
2913
goto errout ;
2914
+
2923
2915
status |= DO_SETLINK_MODIFIED ;
2924
2916
}
2925
2917
@@ -3283,6 +3275,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
3283
3275
struct net * net = sock_net (skb -> sk );
3284
3276
struct nlattr * tb [IFLA_MAX + 1 ];
3285
3277
struct net_device * dev = NULL ;
3278
+ struct net * tgt_net ;
3286
3279
int err ;
3287
3280
3288
3281
err = nlmsg_parse_deprecated (nlh , sizeof (* ifm ), tb , IFLA_MAX ,
@@ -3294,6 +3287,12 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
3294
3287
if (err < 0 )
3295
3288
goto errout ;
3296
3289
3290
+ tgt_net = rtnl_link_get_net_capable (skb , net , tb , CAP_NET_ADMIN );
3291
+ if (IS_ERR (tgt_net )) {
3292
+ err = PTR_ERR (tgt_net );
3293
+ goto errout ;
3294
+ }
3295
+
3297
3296
if (ifm -> ifi_index > 0 )
3298
3297
dev = __dev_get_by_index (net , ifm -> ifi_index );
3299
3298
else if (tb [IFLA_IFNAME ] || tb [IFLA_ALT_IFNAME ])
@@ -3302,10 +3301,11 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
3302
3301
err = - EINVAL ;
3303
3302
3304
3303
if (dev )
3305
- err = do_setlink (skb , dev , ifm , extack , tb , 0 );
3304
+ err = do_setlink (skb , dev , tgt_net , ifm , extack , tb , 0 );
3306
3305
else if (!err )
3307
3306
err = - ENODEV ;
3308
3307
3308
+ put_net (tgt_net );
3309
3309
errout :
3310
3310
return err ;
3311
3311
}
@@ -3599,7 +3599,7 @@ static int rtnl_changelink(const struct sk_buff *skb, struct nlmsghdr *nlh,
3599
3599
status |= DO_SETLINK_NOTIFY ;
3600
3600
}
3601
3601
3602
- return do_setlink (skb , dev , nlmsg_data (nlh ), extack , tb , status );
3602
+ return do_setlink (skb , dev , tgt_net , nlmsg_data (nlh ), extack , tb , status );
3603
3603
}
3604
3604
3605
3605
static int rtnl_group_changelink (const struct sk_buff * skb ,
@@ -3613,7 +3613,7 @@ static int rtnl_group_changelink(const struct sk_buff *skb,
3613
3613
3614
3614
for_each_netdev_safe (net , dev , aux ) {
3615
3615
if (dev -> group == group ) {
3616
- err = do_setlink (skb , dev , ifm , extack , tb , 0 );
3616
+ err = do_setlink (skb , dev , tgt_net , ifm , extack , tb , 0 );
3617
3617
if (err < 0 )
3618
3618
return err ;
3619
3619
}
0 commit comments