Netdev Archive on lore.kernel.org
help / color / mirror / Atom feed
From: ebiederm@xmission.com (Eric W. Biederman)
To: Andrey Ignatov <rdna@fb.com>
Cc: <netdev@vger.kernel.org>, <davem@davemloft.net>,
<kuba@kernel.org>, <kernel-team@fb.com>
Subject: Re: [PATCH net] rtnetlink: Return correct error on changing device netns
Date: Thu, 26 Aug 2021 11:15:22 -0500 [thread overview]
Message-ID: <8735qwi3mt.fsf@disp2133> (raw)
In-Reply-To: <20210826002540.11306-1-rdna@fb.com> (Andrey Ignatov's message of "Wed, 25 Aug 2021 17:25:40 -0700")
Andrey Ignatov <rdna@fb.com> writes:
> 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: d8a5ec672768 ("[NET]: netlink support for moving devices between network namespaces.")
> Signed-off-by: Andrey Ignatov <rdna@fb.com>
The analysis and the fix looks good to me.
The code calling do_setlink is inconsistent. One caller of do_setlink
passes a NULL to indicate not name has been specified. Other callers
pass a string of zero bytes to indicate no name has been specified.
I wonder if we might want to fix the callers to uniformly pass NULL,
instead of a string of length zero.
There is a slight chance this will trigger a regression somewhere
because we are changing the error code but this change looks easy enough
to revert in the unlikely event this breaks existing userspace.
Reviewed-by: "Eric W. Biederman" <ebiederm@xmission.com>
> ---
> net/core/rtnetlink.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index f6af3e74fc44..662eb1c37f47 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -2608,6 +2608,7 @@ static int do_setlink(const struct sk_buff *skb,
> return err;
>
> if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD] || tb[IFLA_TARGET_NETNSID]) {
> + const char *pat = ifname && ifname[0] ? ifname : NULL;
> struct net *net;
> int new_ifindex;
>
> @@ -2623,7 +2624,7 @@ static int do_setlink(const struct sk_buff *skb,
> else
> new_ifindex = 0;
>
> - err = __dev_change_net_namespace(dev, net, ifname, new_ifindex);
> + err = __dev_change_net_namespace(dev, net, pat, new_ifindex);
> put_net(net);
> if (err)
> goto errout;
next prev parent reply other threads:[~2021-08-26 16:16 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-26 0:25 Andrey Ignatov
2021-08-26 11:10 ` patchwork-bot+netdevbpf
2021-08-26 16:15 ` Eric W. Biederman [this message]
2021-08-30 14:59 ` Stephen Hemminger
2021-08-30 16:43 ` Jakub Kicinski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8735qwi3mt.fsf@disp2133 \
--to=ebiederm@xmission.com \
--cc=davem@davemloft.net \
--cc=kernel-team@fb.com \
--cc=kuba@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=rdna@fb.com \
--subject='Re: [PATCH net] rtnetlink: Return correct error on changing device netns' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).