linux/net
Andrey Ignatov ad0db83855 rtnetlink: Return correct error on changing device netns
[ Upstream commit 96a6b93b69 ]

Currently when device is moved between network namespaces using
RTM_NEWLINK message type and one of netns attributes (FLA_NET_NS_PID,
IFLA_NET_NS_FD, IFLA_TARGET_NETNSID) but w/o specifying IFLA_IFNAME, and
target namespace already has device with same name, userspace will get
EINVAL what is confusing and makes debugging harder.

Fix it so that userspace gets more appropriate EEXIST instead what makes
debugging much easier.

Before:

  # ./ifname.sh
  + ip netns add ns0
  + ip netns exec ns0 ip link add l0 type dummy
  + ip netns exec ns0 ip link show l0
  8: l0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
      link/ether 66:90:b5:d5:78:69 brd ff:ff:ff:ff:ff:ff
  + ip link add l0 type dummy
  + ip link show l0
  10: l0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
      link/ether 6e:c6:1f:15:20:8d brd ff:ff:ff:ff:ff:ff
  + ip link set l0 netns ns0
  RTNETLINK answers: Invalid argument

After:

  # ./ifname.sh
  + ip netns add ns0
  + ip netns exec ns0 ip link add l0 type dummy
  + ip netns exec ns0 ip link show l0
  8: l0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
      link/ether 1e:4a:72:e3:e3:8f brd ff:ff:ff:ff:ff:ff
  + ip link add l0 type dummy
  + ip link show l0
  10: l0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
      link/ether f2:fc:fe:2b:7d:a6 brd ff:ff:ff:ff:ff:ff
  + ip link set l0 netns ns0
  RTNETLINK answers: File exists

The problem is that do_setlink() passes its `char *ifname` argument,
that it gets from a caller, to __dev_change_net_namespace() as is (as
`const char *pat`), but semantics of ifname and pat can be different.

For example, __rtnl_newlink() does this:

net/core/rtnetlink.c
    3270	char ifname[IFNAMSIZ];
     ...
    3286	if (tb[IFLA_IFNAME])
    3287		nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
    3288	else
    3289		ifname[0] = '\0';
     ...
    3364	if (dev) {
     ...
    3394		return do_setlink(skb, dev, ifm, extack, tb, ifname, status);
    3395	}

, i.e. do_setlink() gets ifname pointer that is always valid no matter
if user specified IFLA_IFNAME or not and then do_setlink() passes this
ifname pointer as is to __dev_change_net_namespace() as pat argument.

But the pat (pattern) in __dev_change_net_namespace() is used as:

net/core/dev.c
   11198	err = -EEXIST;
   11199	if (__dev_get_by_name(net, dev->name)) {
   11200		/* We get here if we can't use the current device name */
   11201		if (!pat)
   11202			goto out;
   11203		err = dev_get_valid_name(net, dev, pat);
   11204		if (err < 0)
   11205			goto out;
   11206	}

As the result the `goto out` path on line 11202 is neven taken and
instead of returning EEXIST defined on line 11198,
__dev_change_net_namespace() returns an error from dev_get_valid_name()
and this, in turn, will be EINVAL for ifname[0] = '\0' set earlier.

Fixes: d8a5ec6727 ("[NET]: netlink support for moving devices between network namespaces.")
Signed-off-by: Andrey Ignatov <rdna@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2021-09-03 10:09:25 +02:00
..
6lowpan
9p
802 net/802/garp: fix memleak in garp_request_join() 2021-07-31 08:16:11 +02:00
8021q
appletalk
atm
ax25
batman-adv batman-adv: Avoid WARN_ON timing related checks 2021-06-23 14:42:41 +02:00
bluetooth Bluetooth: hidp: use correct wait queue when removing ctrl_wait 2021-08-26 08:35:40 -04:00
bpf bpf: Fix NULL pointer dereference in bpf_get_local_storage() helper 2021-09-03 10:09:21 +02:00
bpfilter bpfilter: Specify the log level for the kmsg message 2021-07-14 16:56:29 +02:00
bridge net: bridge: fix memleak in br_add_if() 2021-08-18 08:59:13 +02:00
caif net: fix uninit-value in caif_seqpkt_sendmsg 2021-07-28 14:35:38 +02:00
can can: j1939: j1939_session_deactivate(): clarify lifetime of session object 2021-08-04 12:46:45 +02:00
ceph
core rtnetlink: Return correct error on changing device netns 2021-09-03 10:09:25 +02:00
dcb
dccp dccp: add do-while-0 stubs for dccp_pr_debug macros 2021-08-26 08:35:41 -04:00
decnet net: decnet: Fix sleeping inside in af_decnet 2021-07-28 14:35:38 +02:00
dns_resolver
dsa net: dsa: properly check for the bridge_leave methods in dsa_switch_bridge_leave() 2021-07-25 14:36:20 +02:00
ethernet
ethtool net: ethtool: clear heap allocations for ethtool function 2021-06-30 08:47:20 -04:00
hsr net: hsr: fix mac_len checks 2021-06-03 09:00:50 +02:00
ieee802154 net: Fix memory leak in ieee802154_raw_deliver 2021-08-18 08:59:12 +02:00
ife
ipv4 ipv4: use siphash instead of Jenkins in fnhe_hashfun() 2021-09-03 10:09:25 +02:00
ipv6 ipv6: use siphash in rt6_exception_hash() 2021-09-03 10:09:24 +02:00
iucv
kcm
key
l2tp
l3mdev
lapb
llc net: llc: fix skb_over_panic 2021-08-04 12:46:43 +02:00
mac80211 mac80211: fix enabling 4-address mode on a sta vif after assoc 2021-08-04 12:46:42 +02:00
mac802154
mpls
mptcp mptcp: fix warning in __skb_flow_dissect() when do syn cookie for subflow join 2021-07-28 14:35:34 +02:00
ncsi
netfilter netfilter: conntrack: collect all entries in one cycle 2021-09-03 10:09:21 +02:00
netlabel netlabel: Fix memory leak in netlbl_mgmt_add_common 2021-07-14 16:56:22 +02:00
netlink netlink: disable IRQs for netlink_lock_table() 2021-06-16 12:01:36 +02:00
netrom netrom: Decrease sock refcount when sock timers expire 2021-07-28 14:35:38 +02:00
nfc net/nfc/rawsock.c: fix a permission check bug 2021-06-16 12:01:35 +02:00
nsh
openvswitch ovs: clear skb->tstamp in forwarding path 2021-08-26 08:35:50 -04:00
packet net/packet: annotate accesses to po->ifindex 2021-06-30 08:47:22 -04:00
phonet
psample
qrtr net: qrtr: fix another OOB Read in qrtr_endpoint_post 2021-09-03 10:09:21 +02:00
rds net: rds: fix memory leak in rds_recvmsg 2021-06-23 14:42:42 +02:00
rfkill
rose
rxrpc
sched net/sched: ets: fix crash when flipping from 'strict' to 'quantum' 2021-09-03 10:09:24 +02:00
sctp sctp: move the active_key update after sh_keys is added 2021-08-12 13:22:06 +02:00
smc net/smc: fix wait on already cleared link 2021-08-18 08:59:10 +02:00
strparser
sunrpc SUNRPC: prevent port reuse on transports which don't request it. 2021-07-20 16:05:51 +02:00
switchdev
tipc tipc: do not write skb_shinfo frags when doing decrytion 2021-08-04 12:46:43 +02:00
tls tls: prevent oversized sendfile() hangs by ignoring MSG_MORE 2021-07-14 16:56:24 +02:00
unix af_unix: fix garbage collect vs MSG_PEEK 2021-07-31 08:16:11 +02:00
vmw_vsock vsock/virtio: avoid potential deadlock when vsock device remove 2021-08-18 08:59:14 +02:00
wimax
wireless cfg80211: Fix possible memory leak in function cfg80211_bss_update 2021-08-04 12:46:41 +02:00
x25 net/x25: Return the correct errno code 2021-06-18 10:00:06 +02:00
xdp xsk: Fix broken Tx ring validation 2021-07-14 16:56:23 +02:00
xfrm net: xfrm: Fix end of loop tests for list_for_each_entry 2021-08-26 08:35:35 -04:00
compat.c net: Return the correct errno code 2021-06-18 10:00:06 +02:00
devres.c
Kconfig
Makefile
socket.c net: make get_net_ns return error if NET_NS is disabled 2021-06-23 14:42:44 +02:00
sysctl_net.c