Skip to content

portal/sysfs: fix NULL-deref creating a dir under a net-namespaced kobject#94

Open
lacraig2 wants to merge 1 commit into
mainfrom
fix-sysfs-netdev-ns-pr
Open

portal/sysfs: fix NULL-deref creating a dir under a net-namespaced kobject#94
lacraig2 wants to merge 1 commit into
mainfrom
fix-sysfs-netdev-ns-pr

Conversation

@lacraig2

Copy link
Copy Markdown
Contributor

Problem

handle_op_sysfs_create_or_lookup_dir() creates directories with
kobject_create_and_add(), whose kobject uses dynamic_kobj_ktype — which has a
NULL .namespace op.

That is fine under most parents, but when the new directory's parent is
network-namespaced — anything under /sys/class/net/<if> or
/sys/devices/virtual/net/<if>, where the parent ktype's child_ns_type reports
KOBJ_NS_TYPE_NET — the kernel's create_dir() -> kobject_namespace() path calls
kobj->ktype->namespace(kobj) unconditionally. With a NULL op this is a
NULL-pointer dereference:

Unable to handle kernel paging request at virtual address 00000000, epc == 00000000
ra == kobject_add_internal+0x98
  kobject_create_and_add -> kobject_add -> kobject_add_internal
  -> handle_op_sysfs_create_or_lookup_dir [igloo]

It runs in the context of whatever task triggered the portal op and was observed
landing on PID 1 (preinit), killing the boot. Non-net parents (e.g.
/sys/bus/usb, other /sys/class/*) have no child_ns_type, so the op is never
invoked there — which is why only netdev-anchored portal dirs crashed.

A second, related issue: the "hook an existing dir" lookup used ns == NULL, which
misses a net-namespaced existing child (e.g. an interface directory). The portal
then fell through to creating it and hit -EEXIST.

Fix

  • Create portal directories with a dedicated kobj_type (portal_dir_ktype) that
    provides a non-NULL .namespace returning the creating task's network namespace,
    plus .sysfs_ops = kobj_sysfs_ops (so kobj_attribute files created inside still
    dispatch show/store) and a .release that frees the kobject.
  • Look the directory up with the matching namespace (portal_child_ns) so an
    existing net-namespaced child is hooked instead of failing the ns == NULL
    lookup and then hitting -EEXIST on create.

Version-guarded .namespace signature (const kobject from v6.2).

Effect

Creating sysfs subdirectories (and attribute files) under an existing netdev
kobject via the portal now works. Verified on a 6.13 mipsel guest: create + read +
write of attributes under a netdev-anchored directory, with the show/store
callbacks dispatching correctly and no Oops (previously 5 Oopses / boot,
sometimes fatal on PID 1).

…bject

handle_op_sysfs_create_or_lookup_dir() created directories with
kobject_create_and_add(), whose kobject uses dynamic_kobj_ktype with a NULL
.namespace op. When the parent directory is network-namespaced -- anything under
/sys/class/net/<if> or /sys/devices/virtual/net/<if>, where the parent ktype's
child_ns_type reports KOBJ_NS_TYPE_NET -- the kernel's create_dir() ->
kobject_namespace() path calls kobj->ktype->namespace(kobj) unconditionally. With
a NULL op this is a NULL-deref Oops; it runs in the context of whatever task
triggered the portal op and was observed landing on PID 1 and killing the boot.
Non-net parents (e.g. /sys/bus/usb) have no child_ns_type, so the op is never
called there -- which is why only netdev-anchored portal dirs crashed.

Two parts:
  - Create portal dirs with a dedicated kobj_type (portal_dir_ktype) that provides
    a non-NULL .namespace returning the creating task's net ns, plus .sysfs_ops =
    kobj_sysfs_ops (so kobj_attribute files created inside still dispatch
    show/store) and a .release that frees the kobject.
  - Look the dir up with the matching namespace (portal_child_ns), so an existing
    net-namespaced child (e.g. an interface dir) is HOOKED instead of failing the
    ns==NULL lookup and then hitting -EEXIST on create.

Enables creating sysfs subdirectories (and attribute files) under an existing
netdev kobject via the portal. Verified: create + read + write of attributes under
a netdev-anchored directory now works with no Oops.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant