All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Pirko <jiri@resnulli.us>
To: Jakub Kicinski <kuba@kernel.org>
Cc: davem@davemloft.net, netdev@vger.kernel.org, edumazet@google.com,
	pabeni@redhat.com, przemyslaw.kitszel@intel.com,
	daniel@iogearbox.net, opurdila@ixiacom.com
Subject: Re: [PATCH net v2 1/5] net: fix ifname in netlink ntf during netns move
Date: Wed, 18 Oct 2023 09:12:58 +0200	[thread overview]
Message-ID: <ZS+FehME4fC4b7w4@nanopsycho> (raw)
In-Reply-To: <20231018013817.2391509-2-kuba@kernel.org>

Wed, Oct 18, 2023 at 03:38:13AM CEST, kuba@kernel.org wrote:
>dev_get_valid_name() overwrites the netdev's name on success.
>This makes it hard to use in prepare-commit-like fashion,
>where we do validation first, and "commit" to the change
>later.
>
>Factor out a helper which lets us save the new name to a buffer.
>Use it to fix the problem of notification on netns move having
>incorrect name:
>
> 5: eth0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
>     link/ether be:4d:58:f9:d5:40 brd ff:ff:ff:ff:ff:ff
> 6: eth1: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
>     link/ether 1e:4a:34:36:e3:cd brd ff:ff:ff:ff:ff:ff
>
> [ ~]# ip link set dev eth0 netns 1 name eth1
>
>ip monitor inside netns:
> Deleted inet eth0
> Deleted inet6 eth0
> Deleted 5: eth1: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default
>     link/ether be:4d:58:f9:d5:40 brd ff:ff:ff:ff:ff:ff new-netnsid 0 new-ifindex 7
>
>Name is reported as eth1 in old netns for ifindex 5, already renamed.
>
>Fixes: d90310243fd7 ("net: device name allocation cleanups")
>Signed-off-by: Jakub Kicinski <kuba@kernel.org>
>---
>v2:
> - use a temp buffer in dev_get_valid_name() to avoid
>   clobering dev->name on error
> - move dev_prep_valid_name() up a bit, this will help later
>   cleanups in net-next
>
>CC: daniel@iogearbox.net
>CC: opurdila@ixiacom.com
>---
> net/core/dev.c | 44 +++++++++++++++++++++++++++++++-------------
> 1 file changed, 31 insertions(+), 13 deletions(-)
>
>diff --git a/net/core/dev.c b/net/core/dev.c
>index 5aaf5753d4e4..f109ad34d660 100644
>--- a/net/core/dev.c
>+++ b/net/core/dev.c
>@@ -1123,6 +1123,26 @@ static int __dev_alloc_name(struct net *net, const char *name, char *buf)
> 	return -ENFILE;
> }
> 
>+static int dev_prep_valid_name(struct net *net, struct net_device *dev,
>+			       const char *want_name, char *out_name)
>+{
>+	int ret;
>+
>+	if (!dev_valid_name(want_name))
>+		return -EINVAL;
>+
>+	if (strchr(want_name, '%')) {
>+		ret = __dev_alloc_name(net, want_name, out_name);
>+		return ret < 0 ? ret : 0;
>+	} else if (netdev_name_in_use(net, want_name)) {
>+		return -EEXIST;
>+	} else if (out_name != want_name) {

How this can happen?
You call dev_prep_valid_name() twice:
	ret = dev_prep_valid_name(net, dev, name, buf);
	err = dev_prep_valid_name(net, dev, pat, new_name);

Both buf and new_name are on stack tmp variables.


>+		strscpy(out_name, want_name, IFNAMSIZ);

You don't need the strscpy here, callers do that.


>+	}
>+
>+	return 0;
>+}
>+
> static int dev_alloc_name_ns(struct net *net,
> 			     struct net_device *dev,
> 			     const char *name)
>@@ -1160,19 +1180,13 @@ EXPORT_SYMBOL(dev_alloc_name);
> static int dev_get_valid_name(struct net *net, struct net_device *dev,
> 			      const char *name)
> {
>-	BUG_ON(!net);
>+	char buf[IFNAMSIZ];
>+	int ret;
> 
>-	if (!dev_valid_name(name))
>-		return -EINVAL;
>-
>-	if (strchr(name, '%'))
>-		return dev_alloc_name_ns(net, dev, name);
>-	else if (netdev_name_in_use(net, name))
>-		return -EEXIST;
>-	else if (dev->name != name)
>-		strscpy(dev->name, name, IFNAMSIZ);
>-
>-	return 0;
>+	ret = dev_prep_valid_name(net, dev, name, buf);
>+	if (ret >= 0)

How ret could be bigger than 0?


>+		strscpy(dev->name, buf, IFNAMSIZ);
>+	return ret;
> }
> 
> /**
>@@ -11038,6 +11052,7 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
> 			       const char *pat, int new_ifindex)
> {
> 	struct net *net_old = dev_net(dev);
>+	char new_name[IFNAMSIZ] = {};
> 	int err, new_nsid;
> 
> 	ASSERT_RTNL();
>@@ -11064,7 +11079,7 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
> 		/* We get here if we can't use the current device name */
> 		if (!pat)
> 			goto out;
>-		err = dev_get_valid_name(net, dev, pat);
>+		err = dev_prep_valid_name(net, dev, pat, new_name);
> 		if (err < 0)
> 			goto out;
> 	}
>@@ -11135,6 +11150,9 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
> 	kobject_uevent(&dev->dev.kobj, KOBJ_ADD);
> 	netdev_adjacent_add_links(dev);
> 
>+	if (new_name[0]) /* Rename the netdev to prepared name */

strlen() would probably read a bit nicer?


>+		strscpy(dev->name, new_name, IFNAMSIZ);
>+
> 	/* Fixup kobjects */
> 	err = device_rename(&dev->dev, dev->name);
> 	WARN_ON(err);
>-- 
>2.41.0
>

  reply	other threads:[~2023-10-18  7:13 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-18  1:38 [PATCH net v2 0/5] net: fix bugs in device netns-move and rename Jakub Kicinski
2023-10-18  1:38 ` [PATCH net v2 1/5] net: fix ifname in netlink ntf during netns move Jakub Kicinski
2023-10-18  7:12   ` Jiri Pirko [this message]
2023-10-18 15:13     ` Jakub Kicinski
2023-10-19 13:42       ` Jiri Pirko
2023-10-18  1:38 ` [PATCH net v2 2/5] net: check for altname conflicts when changing netdev's netns Jakub Kicinski
2023-10-18  1:38 ` [PATCH net v2 3/5] net: avoid UAF on deleted altname Jakub Kicinski
2023-10-18  1:38 ` [PATCH net v2 4/5] net: move altnames together with the netdevice Jakub Kicinski
2023-10-18  1:38 ` [PATCH net v2 5/5] selftests: net: add very basic test for netdev names and namespaces Jakub Kicinski
2023-10-18 20:30   ` Przemek Kitszel
2023-10-19 14:00 ` [PATCH net v2 0/5] net: fix bugs in device netns-move and rename patchwork-bot+netdevbpf

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=ZS+FehME4fC4b7w4@nanopsycho \
    --to=jiri@resnulli.us \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=kuba@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=opurdila@ixiacom.com \
    --cc=pabeni@redhat.com \
    --cc=przemyslaw.kitszel@intel.com \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.