[PATCH 0/2] selftests/cgroup: fix truncated reads of /proc/self/mounts

From: Shaojie Sun

Date: Mon Sep 21 2026 - 09:40:23 EST


The cgroup selftests read /proc/self/mounts with read_text(), which issued
a single read(2) and treated the result as the whole file. For a seq_file
larger than one page it never is: seq_read_iter() copies out at most one
internal PAGE_SIZE buffer per call and leaves the rest for the next
read(2), no matter how much room the caller's buffer has.

On a machine with ~80 mounts /proc/self/mounts is 7177 bytes, a single
read(2) into the 40K buffer in cg_find_root() returns 4035 bytes, and the
cgroup2 entry starts at offset 4953. cg_find_root() therefore never sees
the unified hierarchy, and all ten test binaries that call
cg_find_unified_root() exit with SKIP "cgroup v2 isn't mounted" without
running a single test. The same truncation hits proc_mount_contains(),
so a mount option listed after the first 4K is reported as absent.

Behind that there is a second failure mode: if the buffer really is too
small and the cut lands inside an entry, strtok() returns NULL for the
missing fields and cg_find_root() dereferences it, so a short read ends in
a segfault rather than a plain "no cgroup2 entry found".

The series fixes both: read_text() reads until the buffer is full or EOF,
and cg_find_root() stops parsing as soon as a field is missing. The write
path is untouched and files that fit in max_len - 1 bytes still return
identical bytes, so callers that read a prefix on purpose, such as
cg_read_strcmp() and the 1-byte read in test_zswap, behave as before.

Tested with the mount table above: test_kill goes from
"1..0 # SKIP cgroup v2 isn't mounted" to "1..4"; with BUF_SIZE forced to
6, the old code segfaults in cg_find_unified_root() where the patched one
returns -1.

Shaojie Sun (2):
selftests/cgroup: read the entire file in read_text()
selftests/cgroup: don't crash on a truncated mount entry in
cg_find_root()

.../selftests/cgroup/lib/cgroup_util.c | 45 ++++++++++++++++---
1 file changed, 39 insertions(+), 6 deletions(-)

--
2.50.1