forked from Minki/linux
net: create reusable function for getting ownership info of sysfs inodes
Make net_ns_get_ownership() reusable by networking code outside of core. This is useful, for example, to allow bridge related sysfs files to be owned by container root. Add a function comment since this is a potentially dangerous function to use given the way that kobject_get_ownership() works by initializing uid and gid before calling .get_ownership(). Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b0e37c0d8a
commit
fbdeaed408
@ -10,6 +10,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/sysctl.h>
|
||||
#include <linux/uidgid.h>
|
||||
|
||||
#include <net/flow.h>
|
||||
#include <net/netns/core.h>
|
||||
@ -170,6 +171,8 @@ extern struct net init_net;
|
||||
struct net *copy_net_ns(unsigned long flags, struct user_namespace *user_ns,
|
||||
struct net *old_net);
|
||||
|
||||
void net_ns_get_ownership(const struct net *net, kuid_t *uid, kgid_t *gid);
|
||||
|
||||
void net_ns_barrier(void);
|
||||
#else /* CONFIG_NET_NS */
|
||||
#include <linux/sched.h>
|
||||
@ -182,6 +185,13 @@ static inline struct net *copy_net_ns(unsigned long flags,
|
||||
return old_net;
|
||||
}
|
||||
|
||||
static inline void net_ns_get_ownership(const struct net *net,
|
||||
kuid_t *uid, kgid_t *gid)
|
||||
{
|
||||
*uid = GLOBAL_ROOT_UID;
|
||||
*gid = GLOBAL_ROOT_GID;
|
||||
}
|
||||
|
||||
static inline void net_ns_barrier(void) {}
|
||||
#endif /* CONFIG_NET_NS */
|
||||
|
||||
|
@ -656,24 +656,6 @@ static const struct attribute_group wireless_group = {
|
||||
#define net_class_groups NULL
|
||||
#endif /* CONFIG_SYSFS */
|
||||
|
||||
static void net_ns_get_ownership(const struct net *net,
|
||||
kuid_t *uid, kgid_t *gid)
|
||||
{
|
||||
if (net) {
|
||||
kuid_t ns_root_uid = make_kuid(net->user_ns, 0);
|
||||
kgid_t ns_root_gid = make_kgid(net->user_ns, 0);
|
||||
|
||||
if (uid_valid(ns_root_uid))
|
||||
*uid = ns_root_uid;
|
||||
|
||||
if (gid_valid(ns_root_gid))
|
||||
*gid = ns_root_gid;
|
||||
} else {
|
||||
*uid = GLOBAL_ROOT_UID;
|
||||
*gid = GLOBAL_ROOT_GID;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYSFS
|
||||
#define to_rx_queue_attr(_attr) \
|
||||
container_of(_attr, struct rx_queue_attribute, attr)
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/user_namespace.h>
|
||||
#include <linux/net_namespace.h>
|
||||
#include <linux/sched/task.h>
|
||||
#include <linux/uidgid.h>
|
||||
|
||||
#include <net/sock.h>
|
||||
#include <net/netlink.h>
|
||||
@ -448,6 +449,33 @@ dec_ucounts:
|
||||
return net;
|
||||
}
|
||||
|
||||
/**
|
||||
* net_ns_get_ownership - get sysfs ownership data for @net
|
||||
* @net: network namespace in question (can be NULL)
|
||||
* @uid: kernel user ID for sysfs objects
|
||||
* @gid: kernel group ID for sysfs objects
|
||||
*
|
||||
* Returns the uid/gid pair of root in the user namespace associated with the
|
||||
* given network namespace.
|
||||
*/
|
||||
void net_ns_get_ownership(const struct net *net, kuid_t *uid, kgid_t *gid)
|
||||
{
|
||||
if (net) {
|
||||
kuid_t ns_root_uid = make_kuid(net->user_ns, 0);
|
||||
kgid_t ns_root_gid = make_kgid(net->user_ns, 0);
|
||||
|
||||
if (uid_valid(ns_root_uid))
|
||||
*uid = ns_root_uid;
|
||||
|
||||
if (gid_valid(ns_root_gid))
|
||||
*gid = ns_root_gid;
|
||||
} else {
|
||||
*uid = GLOBAL_ROOT_UID;
|
||||
*gid = GLOBAL_ROOT_GID;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(net_ns_get_ownership);
|
||||
|
||||
static void unhash_nsid(struct net *net, struct net *last)
|
||||
{
|
||||
struct net *tmp;
|
||||
|
Loading…
Reference in New Issue
Block a user