[LTP] [PATCH] perf_event_open03: Track SUnreclaim growth instead of MemAvailable
Vlastimil Babka
vbabka@suse.com
Tue Jul 21 15:32:33 CEST 2026
On 7/14/26 13:13, Tang Yizhou via ltp wrote:
> From: Tang Yizhou <yizhou.tang@shopee.com>
>
> CVE-2020-25704 leaks a small kmalloc() allocation (the filter's file
> name string) on every failed PERF_EVENT_IOC_SET_FILTER call. The test
> detected this by watching MemAvailable in /proc/meminfo drop by more
> than 100MB over 12M iterations.
>
> MemAvailable is a global, system-wide estimate. It is heavily influenced
> by other memory activities of unrelated processes. This produces
> intermittent false positives: the test passes when run alone but
> occasionally fails when run with other tasks.
>
> An improvement is to track the growth of SUnreclaim instead. It is less
> sensitive to other kinds of memory activities.
Right.
> Also note in the failure output that unreclaimable slab can still grow
> due to unrelated slab activities, so a failure should be confirmed on an
> idle system or with kmemleak before being treated as a regression.
That's true as well.
> Signed-off-by: Tang Yizhou <yizhou.tang@shopee.com>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
> ---
> .../perf_event_open/perf_event_open03.c | 32 ++++++++++++-------
> 1 file changed, 20 insertions(+), 12 deletions(-)
>
> diff --git a/testcases/kernel/syscalls/perf_event_open/perf_event_open03.c b/testcases/kernel/syscalls/perf_event_open/perf_event_open03.c
> index 389cc3511..0cc1c27f0 100644
> --- a/testcases/kernel/syscalls/perf_event_open/perf_event_open03.c
> +++ b/testcases/kernel/syscalls/perf_event_open/perf_event_open03.c
> @@ -77,13 +77,13 @@ static void check_progress(int i)
>
> static void run(void)
> {
> - long diff, diff_total, mem_avail, mem_avail_prev;
> + long diff, diff_total, slab, slab_prev;
> int i, sample;
>
> sample = 0;
> diff_total = 0;
>
> - mem_avail_prev = SAFE_READ_MEMINFO("MemAvailable:");
> + slab_prev = SAFE_READ_MEMINFO("SUnreclaim:");
> tst_timer_start(CLOCK_MONOTONIC);
>
> /* leak about 100MB of RAM */
> @@ -92,28 +92,36 @@ static void run(void)
> check_progress(i);
>
> /*
> - * Every 1200000 iterations, calculate the difference in memory
> - * availability. If the difference is greater than 20 * 1024 (20MB),
> - * increment the sample counter and log the event.
> + * Every 1200000 iterations, calculate how much the unreclaimable
> + * slab has grown. If the increase is greater than 20 * 1024
> + * (20MB), increment the sample counter and log the event.
> */
> if ((i % 1200000) == 0) {
> - mem_avail = SAFE_READ_MEMINFO("MemAvailable:");
> - diff = mem_avail_prev - mem_avail;
> + slab = SAFE_READ_MEMINFO("SUnreclaim:");
> + diff = slab - slab_prev;
> diff_total += diff;
>
> if (diff > 20 * 1024) {
> sample++;
> - tst_res(TINFO, "MemAvailable decreased by %ld kB at iteration %d", diff, i);
> + tst_res(TINFO, "SUnreclaim increased by %ld kB at iteration %d", diff, i);
> }
>
> - mem_avail_prev = mem_avail;
> + slab_prev = slab;
> }
> }
>
> - if ((sample > 5) || (diff_total > 100 * 1024))
> - tst_res(TFAIL, "Likely kernel memory leak detected, total decrease: %ld kB", diff_total);
> - else
> + if ((sample > 5) || (diff_total > 100 * 1024)) {
> + tst_res(TFAIL,
> + "Likely kernel memory leak detected, SUnreclaim increased by %ld kB total",
> + diff_total);
> + tst_res(TINFO,
> + "Unreclaimable slab can also grow due to memory activity from "
> + "any other unrelated process. If this test fails, re-run it on "
> + "an otherwise idle system and/or confirm with kmemleak "
> + "(CONFIG_DEBUG_KMEMLEAK) before treating it as a real regression.");
> + } else {
> tst_res(TPASS, "No memory leak found");
> + }
> }
>
> static void cleanup(void)
More information about the ltp
mailing list