This series adds ve.proc_permissions, the procfs counterpart of
ve.sysfs_permissions. It is a per-VE allowlist of /proc paths that the host
exposes to a container, keyed per VE so the single shared proc tree gives
per-VE answers.

The motivation is GPU support in containers. A containerized GPU workload
needs a few host /proc files visible (the nvidia entries it probes), and
ve.proc_permissions exposes them through a generic per-VE allowlist rather
than an nvidia specific passthrough.

While implementing it I found several pre-existing defects in the shared
sysfs and kernfs per-VE permission path, so the series is fix-first. Reading
ve.sysfs_permissions under load already panicked the host on a stock kernel
(NULL deref in kmapset_lookup), which the early patches fix before the procfs
work builds on the same code. Of these defects the ve_perms_map
use-after-free in patch 5 (the __rcu annotation) was found by code analysis.
The rest surfaced through testing, the NULL deref and the wrong rwsem from the
runtime crash and lockdep, and the rcu-list walks from PROVE_RCU_LIST.

Layout:
  1: lib/kmapset annotates the kmapset_lookup rcu-list walk so it is honest
     under CONFIG_PROVE_RCU_LIST.
  2 to 5: fix the kernfs seq read and the VFS readers, skip a NULL map, lock
     the tree that is actually walked, take rcu_read_lock around the kmapset
     lookup, and mark ve_perms_map __rcu to close a use-after-free.
  6: factors the filesystem agnostic core into fs/ve_perms.c with no
     functional change beyond an rcu_assign_pointer publish.
  7: adds the procfs feature on top.
  8 and 9: add the ve selftests, factoring the shared helpers into
     ve_selftest.h and adding a ve_perms test that drives both interfaces
     from the host and checks r/w/x enforcement from inside a VE.

Patch 7 notes a known limitation: a container can read its own
ve.proc_permissions, which runs the tree walk under proc_subdir_lock.
ve.sysfs_permissions is the same today. The walk is bounded by the registered
proc tree, not by the number of processes or containers, so it is a latency
concern on writers rather than a crash or hang. Restricting that read is
tracked separately in VSTOR-120574.

Testing: built and booted a debug kernel with KASAN, kmemleak, lockdep and
PROVE_RCU_LIST. Ran concurrent reader, writer and teardown stress on both
ve.sysfs_permissions and ve.proc_permissions, including in-container /proc and
sysfs access and module load and unload to churn the trees. The original NULL
deref reproduces on a stock kernel and no longer crashes with this series. No
KASAN use-after-free, no kmemleak leak, and no rcu-list or lockdep splat in
the ve_perms paths. The new selftests pass under the same debug kernel
(ve_perms 14 of 14 across proc and sysfs, ve_ns_owner 2 of 2). Per-VE
correctness holds on both filesystems: a path becomes visible and readable
inside a container only after it is added to that VE allowlist, access is
revoked when it is removed, the host is unaffected, and the entry never leaks
to another VE.

Changes since v1:
  - New patches 8 and 9, the ve selftests. Patch 8 factors the shared helpers
    into ve_selftest.h, patch 9 adds a ve_perms test that drives
    ve.proc_permissions and ve.sysfs_permissions from the host and checks
    r/w/x enforcement from inside a VE. Added per review request.
  - Patch 7: documented the known limitation above, and replaced the manual
    seq buffer path packing with a small recursive path helper.
  - Patch 5: use rcu_dereference_protected(..., true) for the mutex serialised
    paths instead of naming kernfs_rwsem in the lockdep condition, since the
    serialising mutex is private to the caller.
  - Patch 3: fold the kernfs_root() call into the down_read().
  - Patch 2: spell out how a node ends up with a NULL ve_perms_map.
  - Added Reviewed-by from Pavel Tikhomirov on patches 3 and 4, tightened a
    few commit messages, and added the jira links.

Mirian Shilakadze (9):
  lib/kmapset: annotate the kmapset_lookup rcu-list walk with the held
    lock
  fs/kernfs, ve: skip NULL ve_perms_map in kernfs_perms_shown
  fs/kernfs, ve: lock the walked tree rwsem in kernfs_perms_start
  fs/kernfs, ve: take rcu_read_lock around the ve_perms kmapset lookup
  fs/kernfs, ve: fix ve_perms_map use-after-free, annotate it __rcu
  fs: factor per-VE permission core into ve_perms helpers
  fs/proc, ve: add per-VE ve.proc_permissions
  selftests/ve: factor common helpers into ve_selftest.h
  selftests/ve: add ve_perms test for proc and sysfs

 fs/Makefile                                   |   1 +
 fs/kernfs/ve.c                                | 159 +++-----
 fs/proc/Makefile                              |   1 +
 fs/proc/generic.c                             |  48 ++-
 fs/proc/inode.c                               |   2 +
 fs/proc/internal.h                            |  25 ++
 fs/proc/root.c                                |   1 +
 fs/proc/ve.c                                  | 347 +++++++++++++++++
 fs/sysfs/ve.c                                 |   2 +-
 fs/ve_perms.c                                 | 136 +++++++
 include/linux/kernfs-ve.h                     |   2 +-
 include/linux/kernfs.h                        |   2 +-
 include/linux/ve-perms.h                      |  28 ++
 include/linux/ve.h                            |   1 +
 kernel/ve/ve.c                                |   7 +
 lib/kmapset.c                                 |   3 +-
 tools/testing/selftests/ve/.gitignore         |   1 +
 tools/testing/selftests/ve/Makefile           |   1 +
 tools/testing/selftests/ve/ve_ns_owner_test.c | 111 +-----
 tools/testing/selftests/ve/ve_perms_test.c    | 360 ++++++++++++++++++
 tools/testing/selftests/ve/ve_selftest.h      | 177 +++++++++
 21 files changed, 1204 insertions(+), 211 deletions(-)
 create mode 100644 fs/proc/ve.c
 create mode 100644 fs/ve_perms.c
 create mode 100644 include/linux/ve-perms.h
 create mode 100644 tools/testing/selftests/ve/ve_perms_test.c
 create mode 100644 tools/testing/selftests/ve/ve_selftest.h

--
2.43.0
_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to