Skip to content

Commit 0840556

Browse files
q2venkuba-moo
authored andcommitted
net: Protect dev->name by seqlock.
We will convert ioctl(SIOCGARP) to RCU, and then we need to copy dev->name which is currently protected by rtnl_lock(). This patch does the following: 1) Add seqlock netdev_rename_lock to protect dev->name 2) Add netdev_copy_name() that copies dev->name to buffer under netdev_rename_lock 3) Use netdev_copy_name() in netdev_get_name() and drop devnet_rename_sem Suggested-by: Eric Dumazet <[email protected]> Link: https://lore.kernel.org/netdev/CANn89iJEWs7AYSJqGCUABeVqOCTkErponfZdT5kV-iD=-SajnQ@mail.gmail.com/ Signed-off-by: Kuniyuki Iwashima <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent a428bfc commit 0840556

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

include/linux/netdevice.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3136,6 +3136,7 @@ struct net_device *netdev_get_by_name(struct net *net, const char *name,
31363136
netdevice_tracker *tracker, gfp_t gfp);
31373137
struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
31383138
struct net_device *dev_get_by_napi_id(unsigned int napi_id);
3139+
void netdev_copy_name(struct net_device *dev, char *name);
31393140

31403141
static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
31413142
unsigned short type,

net/core/dev.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -940,6 +940,18 @@ struct net_device *dev_get_by_napi_id(unsigned int napi_id)
940940
}
941941
EXPORT_SYMBOL(dev_get_by_napi_id);
942942

943+
static DEFINE_SEQLOCK(netdev_rename_lock);
944+
945+
void netdev_copy_name(struct net_device *dev, char *name)
946+
{
947+
unsigned int seq;
948+
949+
do {
950+
seq = read_seqbegin(&netdev_rename_lock);
951+
strscpy(name, dev->name, IFNAMSIZ);
952+
} while (read_seqretry(&netdev_rename_lock, seq));
953+
}
954+
943955
/**
944956
* netdev_get_name - get a netdevice name, knowing its ifindex.
945957
* @net: network namespace
@@ -951,7 +963,6 @@ int netdev_get_name(struct net *net, char *name, int ifindex)
951963
struct net_device *dev;
952964
int ret;
953965

954-
down_read(&devnet_rename_sem);
955966
rcu_read_lock();
956967

957968
dev = dev_get_by_index_rcu(net, ifindex);
@@ -960,12 +971,11 @@ int netdev_get_name(struct net *net, char *name, int ifindex)
960971
goto out;
961972
}
962973

963-
strcpy(name, dev->name);
974+
netdev_copy_name(dev, name);
964975

965976
ret = 0;
966977
out:
967978
rcu_read_unlock();
968-
up_read(&devnet_rename_sem);
969979
return ret;
970980
}
971981

@@ -1217,7 +1227,10 @@ int dev_change_name(struct net_device *dev, const char *newname)
12171227

12181228
memcpy(oldname, dev->name, IFNAMSIZ);
12191229

1230+
write_seqlock(&netdev_rename_lock);
12201231
err = dev_get_valid_name(net, dev, newname);
1232+
write_sequnlock(&netdev_rename_lock);
1233+
12211234
if (err < 0) {
12221235
up_write(&devnet_rename_sem);
12231236
return err;
@@ -1257,7 +1270,9 @@ int dev_change_name(struct net_device *dev, const char *newname)
12571270
if (err >= 0) {
12581271
err = ret;
12591272
down_write(&devnet_rename_sem);
1273+
write_seqlock(&netdev_rename_lock);
12601274
memcpy(dev->name, oldname, IFNAMSIZ);
1275+
write_sequnlock(&netdev_rename_lock);
12611276
memcpy(oldname, newname, IFNAMSIZ);
12621277
WRITE_ONCE(dev->name_assign_type, old_assign_type);
12631278
old_assign_type = NET_NAME_RENAMED;
@@ -11403,8 +11418,12 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
1140311418
dev_net_set(dev, net);
1140411419
dev->ifindex = new_ifindex;
1140511420

11406-
if (new_name[0]) /* Rename the netdev to prepared name */
11421+
if (new_name[0]) {
11422+
/* Rename the netdev to prepared name */
11423+
write_seqlock(&netdev_rename_lock);
1140711424
strscpy(dev->name, new_name, IFNAMSIZ);
11425+
write_sequnlock(&netdev_rename_lock);
11426+
}
1140811427

1140911428
/* Fixup kobjects */
1141011429
dev_set_uevent_suppress(&dev->dev, 1);

0 commit comments

Comments
 (0)