summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2026-04-01 12:15:58 +0200
committerChristian Brauner <brauner@kernel.org>2026-04-09 14:36:52 +0200
commite3b2cf6e5dba416a03152f299d99982dfe1e861d (patch)
treed10833a41819fac2d0c066bd80def58a36453228 /net/core
parent07712db80857d5d09ae08f3df85a708ecfc3b61f (diff)
kernfs: pass struct ns_common instead of const void * for namespace tags
kernfs has historically used const void * to pass around namespace tags used for directory-level namespace filtering. The only current user of this is sysfs network namespace tagging where struct net pointers are cast to void *. Replace all const void * namespace parameters with const struct ns_common * throughout the kernfs, sysfs, and kobject namespace layers. This includes the kobj_ns_type_operations callbacks, kobject_namespace(), and all sysfs/kernfs APIs that accept or return namespace tags. Passing struct ns_common is needed because various codepaths require access to the underlying namespace. A struct ns_common can always be converted back to the concrete namespace type (e.g., struct net) via container_of() or to_ns_common() in the reverse direction. This is a preparatory change for switching to ns_id-based directory iteration to prevent a KASLR pointer leak through the current use of raw namespace pointers as hash seeds and comparison keys. Signed-off-by: Christian Brauner <brauner@kernel.org>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/net-sysfs.c50
-rw-r--r--net/core/net_namespace.c8
2 files changed, 28 insertions, 30 deletions
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 07624b682b08..b9740a397f55 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -1181,24 +1181,24 @@ static void rx_queue_release(struct kobject *kobj)
netdev_put(queue->dev, &queue->dev_tracker);
}
-static const void *rx_queue_namespace(const struct kobject *kobj)
+static const struct ns_common *rx_queue_namespace(const struct kobject *kobj)
{
struct netdev_rx_queue *queue = to_rx_queue(kobj);
struct device *dev = &queue->dev->dev;
- const void *ns = NULL;
if (dev->class && dev->class->namespace)
- ns = dev->class->namespace(dev);
+ return dev->class->namespace(dev);
- return ns;
+ return NULL;
}
static void rx_queue_get_ownership(const struct kobject *kobj,
kuid_t *uid, kgid_t *gid)
{
- const struct net *net = rx_queue_namespace(kobj);
+ const struct ns_common *ns = rx_queue_namespace(kobj);
- net_ns_get_ownership(net, uid, gid);
+ net_ns_get_ownership(ns ? container_of(ns, struct net, ns) : NULL,
+ uid, gid);
}
static const struct kobj_type rx_queue_ktype = {
@@ -1931,24 +1931,24 @@ static void netdev_queue_release(struct kobject *kobj)
netdev_put(queue->dev, &queue->dev_tracker);
}
-static const void *netdev_queue_namespace(const struct kobject *kobj)
+static const struct ns_common *netdev_queue_namespace(const struct kobject *kobj)
{
struct netdev_queue *queue = to_netdev_queue(kobj);
struct device *dev = &queue->dev->dev;
- const void *ns = NULL;
if (dev->class && dev->class->namespace)
- ns = dev->class->namespace(dev);
+ return dev->class->namespace(dev);
- return ns;
+ return NULL;
}
static void netdev_queue_get_ownership(const struct kobject *kobj,
kuid_t *uid, kgid_t *gid)
{
- const struct net *net = netdev_queue_namespace(kobj);
+ const struct ns_common *ns = netdev_queue_namespace(kobj);
- net_ns_get_ownership(net, uid, gid);
+ net_ns_get_ownership(ns ? container_of(ns, struct net, ns) : NULL,
+ uid, gid);
}
static const struct kobj_type netdev_queue_ktype = {
@@ -2185,24 +2185,24 @@ static bool net_current_may_mount(void)
return ns_capable(net->user_ns, CAP_SYS_ADMIN);
}
-static void *net_grab_current_ns(void)
+static struct ns_common *net_grab_current_ns(void)
{
- struct net *ns = current->nsproxy->net_ns;
+ struct net *net = current->nsproxy->net_ns;
#ifdef CONFIG_NET_NS
- if (ns)
- refcount_inc(&ns->passive);
+ if (net)
+ refcount_inc(&net->passive);
#endif
- return ns;
+ return net ? to_ns_common(net) : NULL;
}
-static const void *net_initial_ns(void)
+static const struct ns_common *net_initial_ns(void)
{
- return &init_net;
+ return to_ns_common(&init_net);
}
-static const void *net_netlink_ns(struct sock *sk)
+static const struct ns_common *net_netlink_ns(struct sock *sk)
{
- return sock_net(sk);
+ return to_ns_common(sock_net(sk));
}
const struct kobj_ns_type_operations net_ns_type_operations = {
@@ -2252,11 +2252,11 @@ static void netdev_release(struct device *d)
kvfree(dev);
}
-static const void *net_namespace(const struct device *d)
+static const struct ns_common *net_namespace(const struct device *d)
{
const struct net_device *dev = to_net_dev(d);
- return dev_net(dev);
+ return to_ns_common(dev_net(dev));
}
static void net_get_ownership(const struct device *d, kuid_t *uid, kgid_t *gid)
@@ -2402,14 +2402,14 @@ int netdev_change_owner(struct net_device *ndev, const struct net *net_old,
}
int netdev_class_create_file_ns(const struct class_attribute *class_attr,
- const void *ns)
+ const struct ns_common *ns)
{
return class_create_file_ns(&net_class, class_attr, ns);
}
EXPORT_SYMBOL(netdev_class_create_file_ns);
void netdev_class_remove_file_ns(const struct class_attribute *class_attr,
- const void *ns)
+ const struct ns_common *ns)
{
class_remove_file_ns(&net_class, class_attr, ns);
}
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 1057d16d5dd2..24aa10a1d0ea 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -540,12 +540,10 @@ void net_passive_dec(struct net *net)
}
}
-void net_drop_ns(void *p)
+void net_drop_ns(struct ns_common *ns)
{
- struct net *net = (struct net *)p;
-
- if (net)
- net_passive_dec(net);
+ if (ns)
+ net_passive_dec(to_net_ns(ns));
}
struct net *copy_net_ns(u64 flags,