mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/2] selftests/cgroup: fix truncated reads of /proc/self/mounts
@ 2026-09-21 13:15 Shaojie Sun
  2026-09-21 13:15 ` [PATCH 1/2] selftests/cgroup: read the entire file in read_text() Shaojie Sun
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Shaojie Sun @ 2026-09-21 13:15 UTC (permalink / raw)
  To: Tejun Heo, cgroups
  Cc: Johannes Weiner, mkoutny, Shuah Khan, linux-kselftest,
	linux-kernel, Li Wang, Hongfu Li, Shakeel Butt

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


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-09-21 17:23 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-21 13:15 [PATCH 0/2] selftests/cgroup: fix truncated reads of /proc/self/mounts Shaojie Sun
2026-09-21 13:15 ` [PATCH 1/2] selftests/cgroup: read the entire file in read_text() Shaojie Sun
2026-09-21 13:15 ` [PATCH 2/2] selftests/cgroup: don't crash on a truncated mount entry in cg_find_root() Shaojie Sun
2026-09-21 17:23 ` [PATCH 0/2] selftests/cgroup: fix truncated reads of /proc/self/mounts Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®