From: Christian Brauner <christian.brauner@ubuntu.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: "David S. Miller" <davem@davemloft.net>,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
"Rafael J. Wysocki" <rafael@kernel.org>,
Pavel Machek <pavel@ucw.cz>, Jakub Kicinski <kuba@kernel.org>,
Eric Dumazet <edumazet@google.com>,
Stephen Hemminger <stephen@networkplumber.org>,
linux-pm@vger.kernel.org
Subject: Re: [PATCH net-next v2 08/10] net-sysfs: add netdev_change_owner()
Date: Mon, 17 Feb 2020 17:58:54 +0100 [thread overview]
Message-ID: <20200217165854.4ywtbxbaenha3iti@wittgenstein> (raw)
In-Reply-To: <20200217162803.GA1502885@kroah.com>
On Mon, Feb 17, 2020 at 05:28:03PM +0100, Greg Kroah-Hartman wrote:
> On Mon, Feb 17, 2020 at 05:14:34PM +0100, Christian Brauner wrote:
> > Add a function to change the owner of a network device when it is moved
> > between network namespaces.
> >
> > Currently, when moving network devices between network namespaces the
> > ownership of the corresponding sysfs entries is not changed. This leads
> > to problems when tools try to operate on the corresponding sysfs files.
> > This leads to a bug whereby a network device that is created in a
> > network namespaces owned by a user namespace will have its corresponding
> > sysfs entry owned by the root user of the corresponding user namespace.
> > If such a network device has to be moved back to the host network
> > namespace the permissions will still be set to the user namespaces. This
> > means unprivileged users can e.g. trigger uevents for such incorrectly
> > owned devices. They can also modify the settings of the device itself.
> > Both of these things are unwanted.
> >
> > For example, workloads will create network devices in the host network
> > namespace. Other tools will then proceed to move such devices between
> > network namespaces owner by other user namespaces. While the ownership
> > of the device itself is updated in
> > net/core/net-sysfs.c:dev_change_net_namespace() the corresponding sysfs
> > entry for the device is not:
> >
> > drwxr-xr-x 5 nobody nobody 0 Jan 25 18:08 .
> > drwxr-xr-x 9 nobody nobody 0 Jan 25 18:08 ..
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 addr_assign_type
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 addr_len
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 address
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 broadcast
> > -rw-r--r-- 1 nobody nobody 4096 Jan 25 18:09 carrier
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 carrier_changes
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 carrier_down_count
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 carrier_up_count
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 dev_id
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 dev_port
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 dormant
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 duplex
> > -rw-r--r-- 1 nobody nobody 4096 Jan 25 18:09 flags
> > -rw-r--r-- 1 nobody nobody 4096 Jan 25 18:09 gro_flush_timeout
> > -rw-r--r-- 1 nobody nobody 4096 Jan 25 18:09 ifalias
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 ifindex
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 iflink
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 link_mode
> > -rw-r--r-- 1 nobody nobody 4096 Jan 25 18:09 mtu
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 name_assign_type
> > -rw-r--r-- 1 nobody nobody 4096 Jan 25 18:09 netdev_group
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 operstate
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 phys_port_id
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 phys_port_name
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 phys_switch_id
> > drwxr-xr-x 2 nobody nobody 0 Jan 25 18:09 power
> > -rw-r--r-- 1 nobody nobody 4096 Jan 25 18:09 proto_down
> > drwxr-xr-x 4 nobody nobody 0 Jan 25 18:09 queues
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 speed
> > drwxr-xr-x 2 nobody nobody 0 Jan 25 18:09 statistics
> > lrwxrwxrwx 1 nobody nobody 0 Jan 25 18:08 subsystem -> ../../../../class/net
> > -rw-r--r-- 1 nobody nobody 4096 Jan 25 18:09 tx_queue_len
> > -r--r--r-- 1 nobody nobody 4096 Jan 25 18:09 type
> > -rw-r--r-- 1 nobody nobody 4096 Jan 25 18:08 uevent
> >
> > However, if a device is created directly in the network namespace then
> > the device's sysfs permissions will be correctly updated:
> >
> > drwxr-xr-x 5 root root 0 Jan 25 18:12 .
> > drwxr-xr-x 9 nobody nobody 0 Jan 25 18:08 ..
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 addr_assign_type
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 addr_len
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 address
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 broadcast
> > -rw-r--r-- 1 root root 4096 Jan 25 18:12 carrier
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 carrier_changes
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 carrier_down_count
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 carrier_up_count
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 dev_id
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 dev_port
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 dormant
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 duplex
> > -rw-r--r-- 1 root root 4096 Jan 25 18:12 flags
> > -rw-r--r-- 1 root root 4096 Jan 25 18:12 gro_flush_timeout
> > -rw-r--r-- 1 root root 4096 Jan 25 18:12 ifalias
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 ifindex
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 iflink
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 link_mode
> > -rw-r--r-- 1 root root 4096 Jan 25 18:12 mtu
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 name_assign_type
> > -rw-r--r-- 1 root root 4096 Jan 25 18:12 netdev_group
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 operstate
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 phys_port_id
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 phys_port_name
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 phys_switch_id
> > drwxr-xr-x 2 root root 0 Jan 25 18:12 power
> > -rw-r--r-- 1 root root 4096 Jan 25 18:12 proto_down
> > drwxr-xr-x 4 root root 0 Jan 25 18:12 queues
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 speed
> > drwxr-xr-x 2 root root 0 Jan 25 18:12 statistics
> > lrwxrwxrwx 1 nobody nobody 0 Jan 25 18:12 subsystem -> ../../../../class/net
> > -rw-r--r-- 1 root root 4096 Jan 25 18:12 tx_queue_len
> > -r--r--r-- 1 root root 4096 Jan 25 18:12 type
> > -rw-r--r-- 1 root root 4096 Jan 25 18:12 uevent
> >
> > Now, when creating a network device in a network namespace owned by a
> > user namespace and moving it to the host the permissions will be set to
> > the id that the user namespace root user has been mapped to on the host
> > leading to all sorts of permission issues:
> >
> > 458752
> > drwxr-xr-x 5 458752 458752 0 Jan 25 18:12 .
> > drwxr-xr-x 9 root root 0 Jan 25 18:08 ..
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 addr_assign_type
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 addr_len
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 address
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 broadcast
> > -rw-r--r-- 1 458752 458752 4096 Jan 25 18:12 carrier
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 carrier_changes
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 carrier_down_count
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 carrier_up_count
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 dev_id
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 dev_port
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 dormant
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 duplex
> > -rw-r--r-- 1 458752 458752 4096 Jan 25 18:12 flags
> > -rw-r--r-- 1 458752 458752 4096 Jan 25 18:12 gro_flush_timeout
> > -rw-r--r-- 1 458752 458752 4096 Jan 25 18:12 ifalias
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 ifindex
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 iflink
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 link_mode
> > -rw-r--r-- 1 458752 458752 4096 Jan 25 18:12 mtu
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 name_assign_type
> > -rw-r--r-- 1 458752 458752 4096 Jan 25 18:12 netdev_group
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 operstate
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 phys_port_id
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 phys_port_name
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 phys_switch_id
> > drwxr-xr-x 2 458752 458752 0 Jan 25 18:12 power
> > -rw-r--r-- 1 458752 458752 4096 Jan 25 18:12 proto_down
> > drwxr-xr-x 4 458752 458752 0 Jan 25 18:12 queues
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 speed
> > drwxr-xr-x 2 458752 458752 0 Jan 25 18:12 statistics
> > lrwxrwxrwx 1 root root 0 Jan 25 18:12 subsystem -> ../../../../class/net
> > -rw-r--r-- 1 458752 458752 4096 Jan 25 18:12 tx_queue_len
> > -r--r--r-- 1 458752 458752 4096 Jan 25 18:12 type
> > -rw-r--r-- 1 458752 458752 4096 Jan 25 18:12 uevent
> >
> > Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
> > ---
> > /* v2 */
> > unchanged
> > ---
> > net/core/net-sysfs.c | 27 +++++++++++++++++++++++++++
> > net/core/net-sysfs.h | 2 ++
> > 2 files changed, 29 insertions(+)
> >
> > diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
> > index 4c826b8bf9b1..4fda021edf6d 100644
> > --- a/net/core/net-sysfs.c
> > +++ b/net/core/net-sysfs.c
> > @@ -1767,6 +1767,33 @@ int netdev_register_kobject(struct net_device *ndev)
> > return error;
> > }
> >
> > +/* Change owner for sysfs entries when moving network devices across network
> > + * namespaces owned by different user namespaces.
> > + */
> > +int netdev_change_owner(struct net_device *ndev, const struct net *net_old,
> > + const struct net *net_new)
> > +{
> > + struct device *dev = &ndev->dev;
> > + kuid_t old_uid, new_uid;
> > + kgid_t old_gid, new_gid;
> > + int error;
> > +
> > + net_ns_get_ownership(net_old, &old_uid, &old_gid);
> > + net_ns_get_ownership(net_new, &new_uid, &new_gid);
> > +
> > + /* The network namespace was changed but the owning user namespace is
> > + * identical so there's no need to change the owner of sysfs entries.
> > + */
> > + if (uid_eq(old_uid, new_uid) && gid_eq(old_gid, new_gid))
> > + return 0;
> > +
> > + error = device_change_owner(dev);
>
> Ok, maybe I'm slow here, but what actually changed the gid/uid here?
> How did it change? All you did was look up the old uid/gid and the new
> uid/gid. But what set the device to the new one?
>
> All of these functions are just really odd to me, one would think that a
> "change owner" function would have the new owner in the paramter to know
> what to change it to? Your documentation says "owner must be changed
> before calling this function", but how did that get changed and who
> changed it?
>
> Why not just pass it as part of the function itself?
>
> Otherwise it looks really odd, like the above call. As I can't see how
> anything changes here at all by reading this code. And that's a huge
> sign of a bad API, when the maintainer of the subsystem can not even
> understand how someone is using it with a single function call :)
So we've been briefly discussing this in the first iteration of this
series where I also explained why I in the first iteration I didn't add
explicit uid_t and gid_t parameters. I sugggested adding uid_t/gid_t
parameters in that thread but from your response in
https://lore.kernel.org/lkml/20200212160402.GA1799124@kroah.com/:
> > So ownership only changes if the kobject's uid/gid have been changed.
> > So when to stick with the networking example, when a network device is
> > moved into a new network namespace, the uid/gid of the kobject will be
> > changed to the root user of the owning user namespace of that network
> > namespace. So when the move of the network device has completed and
> > kobject_get_ownership() is called it will now return a different
> > uid/gid.
>
> Ok, then this needs to say "change the uid/gid of the kobject to..." in
> order to explain what it is now being set to. Otherwise this is really
> confusing if you only read the kerneldoc, right?
From this answer I took it that you did prefer not adding uid/gid
parameters. If that has changed or I misunderstood you then I can change
all these functions.
For clarity, for network namespaces: when the move of a network device
has completed dev_change_net_namespace() is called which changes the
ownership of the kobject associated with the net device. Now
kobject_get_ownership() will return the updated uids/gids. In any case,
asking explicitly: do you want to have those sysfs and device functions
take explicit uid and gid parameters? That sounds nicer to me as well. I
just didn't want to expose it because we alreay had this dynamic way of
setting ownership via kobject_get_ownership().
Thanks!
Christian
next prev parent reply other threads:[~2020-02-17 16:58 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-17 16:14 [PATCH net-next v2 00/10] net: fix sysfs permssions when device changes network Christian Brauner
2020-02-17 16:14 ` [PATCH net-next v2 01/10] sysfs: add sysfs_file_change_owner{_by_name}() Christian Brauner
2020-02-17 16:29 ` Greg Kroah-Hartman
2020-02-17 16:14 ` [PATCH net-next v2 02/10] sysfs: add sysfs_link_change_owner() Christian Brauner
2020-02-17 16:14 ` [PATCH net-next v2 03/10] sysfs: add sysfs_group_change_owner() Christian Brauner
2020-02-17 16:14 ` [PATCH net-next v2 04/10] sysfs: add sysfs_groups_change_owner() Christian Brauner
2020-02-17 16:14 ` [PATCH net-next v2 05/10] sysfs: add sysfs_change_owner() Christian Brauner
2020-02-17 16:14 ` [PATCH net-next v2 06/10] device: add device_change_owner() Christian Brauner
2020-02-17 16:14 ` [PATCH net-next v2 07/10] drivers/base/power: add dpm_sysfs_change_owner() Christian Brauner
2020-02-17 16:14 ` [PATCH net-next v2 08/10] net-sysfs: add netdev_change_owner() Christian Brauner
2020-02-17 16:28 ` Greg Kroah-Hartman
2020-02-17 16:58 ` Christian Brauner [this message]
2020-02-17 19:02 ` Greg Kroah-Hartman
2020-02-17 16:14 ` [PATCH net-next v2 09/10] net-sysfs: add queue_change_owner() Christian Brauner
2020-02-17 16:14 ` [PATCH net-next v2 10/10] net: fix sysfs permssions when device changes network namespace Christian Brauner
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=20200217165854.4ywtbxbaenha3iti@wittgenstein \
--to=christian.brauner@ubuntu.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=gregkh@linuxfoundation.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pavel@ucw.cz \
--cc=rafael@kernel.org \
--cc=stephen@networkplumber.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®