* [LTP] [PATCH v2 1/2] lib: Validate sysconf() return values in the safe wrapper
[not found] <20261104110021.7870-1-2063309626@qq.com>
@ 2026-11-04 11:00 ` Wenyuan Li via ltp
2026-11-04 11:42 ` [LTP] " linuxtestproject.agent
2026-11-04 12:28 ` [LTP] [PATCH v2 1/2] " Cyril Hrubis
2026-11-04 11:00 ` [LTP] [PATCH v2 2/2] syscalls/madvise13: Check MADV_DONTNEED across an unmapped hole Wenyuan Li via ltp
2026-11-11 12:00 ` [LTP] [PATCH v2 0/2] Harden safe_sysconf() and add madvise13 Wenyuan Li via ltp
2 siblings, 2 replies; 6+ messages in thread
From: Wenyuan Li via ltp @ 2026-11-04 11:00 UTC (permalink / raw)
To: ltp
sysconf() returns -1 either on error (with errno set) or to signal that
the queried option has no definite limit. Any value below -1 is not a
legal return value, so report it as a test environment error instead of
handing it back to the caller unchecked.
For _SC_PAGESIZE also reject values that cannot describe a page size:
-1 without errno (this name has no "indeterminate limit" semantics), 0,
and values that are not a power of two. The generic -1 && !errno path is
deliberately left as TINFO because it is valid for other names such as
_SC_OPEN_MAX.
Audited all 49 SAFE_SYSCONF() call sites in the tree:
_SC_PAGESIZE 32
_SC_PAGE_SIZE 7 (glibc alias of _SC_PAGESIZE)
_SC_CLK_TCK 4
_SC_OPEN_MAX 3
_SC_NPROCESSORS_CONF 2
_SC_NPROCESSORS_ONLN 1
None of them relies on a value below -1 and none expects _SC_PAGESIZE
to be indeterminate, so the new checks only fire on a broken test
environment. The three _SC_OPEN_MAX callers, e.g. the loop bound in
tst_ns_create.c, are exactly why the generic -1 && !errno branch must
stay untouched.
Suggested-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Wenyuan Li <2063309626@qq.com>
---
lib/safe_macros.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/lib/safe_macros.c b/lib/safe_macros.c
index 187550041..40c5f292f 100644
--- a/lib/safe_macros.c
+++ b/lib/safe_macros.c
@@ -700,6 +700,26 @@ long safe_sysconf(const char *file, const int lineno,
}
}
+ if (rval < -1)
+ tst_brkm_(file, lineno, TBROK, cleanup_fn,
+ "sysconf(%d) returned invalid value %ld", name, rval);
+
+ if (name == _SC_PAGESIZE) {
+ /* A -1 with errno set was already reported above. */
+ if (rval == -1)
+ tst_brkm_(file, lineno, TBROK, cleanup_fn,
+ "sysconf(_SC_PAGESIZE) returned -1 without errno");
+
+ if (!rval)
+ tst_brkm_(file, lineno, TBROK, cleanup_fn,
+ "sysconf(_SC_PAGESIZE) returned 0");
+
+ if (rval > 0 && (rval & (rval - 1)))
+ tst_brkm_(file, lineno, TBROK, cleanup_fn,
+ "sysconf(_SC_PAGESIZE) returned %ld, expected a power of two",
+ rval);
+ }
+
return rval;
}
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [LTP] [PATCH v2 2/2] syscalls/madvise13: Check MADV_DONTNEED across an unmapped hole
[not found] <20261104110021.7870-1-2063309626@qq.com>
2026-11-04 11:00 ` [LTP] [PATCH v2 1/2] lib: Validate sysconf() return values in the safe wrapper Wenyuan Li via ltp
@ 2026-11-04 11:00 ` Wenyuan Li via ltp
2026-11-04 16:22 ` Cyril Hrubis
2026-11-11 12:00 ` [LTP] [PATCH v2 0/2] Harden safe_sysconf() and add madvise13 Wenyuan Li via ltp
2 siblings, 1 reply; 6+ messages in thread
From: Wenyuan Li via ltp @ 2026-11-04 11:00 UTC (permalink / raw)
To: ltp
madvise(2) documents that Linux applies the advice to the mapped parts of
a range containing unmapped pages, while returning ENOMEM for the
request. For a private anonymous mapping, MADV_DONTNEED should therefore
discard the contents of the mapped portions on both sides of a hole.
Existing tests do not cover that combination. madvise02 checks the ENOMEM
return for MADV_NORMAL and MADV_WILLNEED on a shared file mapping whose
final page has been unmapped; it does not check MADV_DONTNEED, and it does
not look at the contents of the mapped portions after the call. madvise03
checks zero-fill-on-demand for MADV_DONTNEED on a fully mapped range.
Use eight pages with distinct nonzero byte patterns and advise pages 2
through 4. Run once with all pages mapped and once with page 3 unmapped.
Check the return value, zero-filled target pages, unchanged data outside
the range, and preservation of the hole. Use mincore() to check the hole
without dereferencing it, not to infer physical-page reclamation.
Allocate a fresh mapping for each case, use the runtime page size, and
release the complete region in cleanup, including the case with a hole.
The test does not require root privileges.
Tested on x86-64, 4096-byte pages, kernel 6.18.54.1: 18 TPASS, 36 TPASS
with -i 2.
Link: https://man7.org/linux/man-pages/man2/madvise.2.html
Signed-off-by: Wenyuan Li <2063309626@qq.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/madvise/.gitignore | 1 +
testcases/kernel/syscalls/madvise/madvise13.c | 154 ++++++++++++++++++
3 files changed, 156 insertions(+)
create mode 100644 testcases/kernel/syscalls/madvise/madvise13.c
diff --git a/runtest/syscalls b/runtest/syscalls
index ff3de1b15..48cbdab39 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -1095,6 +1095,7 @@ madvise09 madvise09
madvise10 madvise10
madvise11 madvise11
madvise12 madvise12
+madvise13 madvise13
newuname01 newuname01
diff --git a/testcases/kernel/syscalls/madvise/.gitignore b/testcases/kernel/syscalls/madvise/.gitignore
index 758e601a9..3e7dbe653 100644
--- a/testcases/kernel/syscalls/madvise/.gitignore
+++ b/testcases/kernel/syscalls/madvise/.gitignore
@@ -9,3 +9,4 @@
/madvise10
/madvise11
/madvise12
+/madvise13
diff --git a/testcases/kernel/syscalls/madvise/madvise13.c b/testcases/kernel/syscalls/madvise/madvise13.c
new file mode 100644
index 000000000..cb4323e5b
--- /dev/null
+++ b/testcases/kernel/syscalls/madvise/madvise13.c
@@ -0,0 +1,154 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Wenyuan Li <2063309626@qq.com>
+ */
+
+/*\
+ * Verify MADV_DONTNEED on a private anonymous range containing an unmapped
+ * page. The call must return ENOMEM but still discard the mapped pages on
+ * both sides of the hole, without changing data outside the requested range.
+ * Also test the same request with the middle page mapped.
+ *
+ * madvise(2), VERSIONS/Linux, specifies that Linux applies the advice to
+ * the mapped parts of a range containing holes, even though it returns
+ * ENOMEM.
+ */
+
+#include <sys/mman.h>
+#include "tst_test.h"
+#include "lapi/mmap.h"
+
+#define PAGES 8
+#define HOLE_PAGE 3
+/* Test-local range, not a madvise(2) advice. */
+#define RANGE_FIRST 2
+#define RANGE_LAST 4
+#define RANGE_PAGES (RANGE_LAST - RANGE_FIRST + 1)
+
+static unsigned char *addr;
+static size_t page_size;
+
+static void cleanup(void)
+{
+ if (addr) {
+ SAFE_MUNMAP(addr, PAGES * page_size);
+ addr = NULL;
+ }
+}
+
+/*
+ * Return 1 if the page is mapped, 0 if mincore() reports ENOMEM (a hole).
+ * Any other mincore() failure is a test library error.
+ */
+static int page_mapped(unsigned int page)
+{
+ unsigned char vec;
+
+ TEST(mincore(addr + page * page_size, page_size, &vec));
+
+ if (TST_RET == -1) {
+ if (TST_ERR == ENOMEM)
+ return 0;
+
+ tst_brk(TBROK | TTERRNO, "mincore() on page %u", page);
+ }
+
+ return 1;
+}
+
+/*
+ * Return the offset of the first byte that differs from expected, or
+ * page_size when the whole page matches.
+ */
+static size_t page_first_mismatch(unsigned int page, unsigned char expected)
+{
+ unsigned char *ptr = addr + page * page_size;
+ size_t i;
+
+ for (i = 0; i < page_size; i++) {
+ if (ptr[i] != expected)
+ return i;
+ }
+
+ return page_size;
+}
+
+static void run(unsigned int hole)
+{
+ unsigned int page;
+ unsigned char expected;
+ size_t off;
+
+ tst_res(TINFO, "MADV_DONTNEED %s a hole", hole ? "across" : "without");
+
+ addr = SAFE_MMAP(NULL, PAGES * page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ for (page = 0; page < PAGES; page++) {
+ if (!page_mapped(page))
+ tst_brk(TBROK, "Page %u is not mapped after mmap()", page);
+
+ memset(addr + page * page_size, 0x40 + page, page_size);
+
+ off = page_first_mismatch(page, 0x40 + page);
+ if (off != page_size)
+ tst_brk(TBROK, "Page %u byte %zu was not initialized", page, off);
+ }
+
+ if (hole) {
+ SAFE_MUNMAP(addr + HOLE_PAGE * page_size, page_size);
+
+ if (page_mapped(HOLE_PAGE))
+ tst_brk(TBROK, "The hole was not created");
+
+ TST_EXP_FAIL(madvise(addr + RANGE_FIRST * page_size,
+ RANGE_PAGES * page_size, MADV_DONTNEED), ENOMEM);
+ } else {
+ TST_EXP_PASS(madvise(addr + RANGE_FIRST * page_size,
+ RANGE_PAGES * page_size, MADV_DONTNEED));
+ }
+
+ for (page = 0; page < PAGES; page++) {
+ if (hole && page == HOLE_PAGE)
+ continue;
+
+ expected = 0x40 + page;
+ if (page >= RANGE_FIRST && page <= RANGE_LAST)
+ expected = 0;
+
+ if (!page_mapped(page)) {
+ tst_res(TFAIL, "Page %u is no longer mapped", page);
+ continue;
+ }
+
+ off = page_first_mismatch(page, expected);
+ if (off == page_size) {
+ tst_res(TPASS, "Page %u contains only %#x", page, expected);
+ } else {
+ tst_res(TFAIL, "Page %u byte %zu: expected %#x, got %#x",
+ page, off, expected,
+ addr[page * page_size + off]);
+ }
+ }
+
+ if (hole) {
+ if (page_mapped(HOLE_PAGE))
+ tst_res(TFAIL, "The hole is mapped after MADV_DONTNEED");
+ else
+ tst_res(TPASS, "The hole remains unmapped");
+ }
+
+ cleanup();
+}
+
+static void setup(void)
+{
+ page_size = SAFE_SYSCONF(_SC_PAGESIZE);
+}
+
+static struct tst_test test = {
+ .test = run,
+ .tcnt = 2,
+ .setup = setup,
+ .cleanup = cleanup,
+};
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [LTP] lib: Validate sysconf() return values in the safe wrapper
2026-11-04 11:00 ` [LTP] [PATCH v2 1/2] lib: Validate sysconf() return values in the safe wrapper Wenyuan Li via ltp
@ 2026-11-04 11:42 ` linuxtestproject.agent
2026-11-04 12:28 ` [LTP] [PATCH v2 1/2] " Cyril Hrubis
1 sibling, 0 replies; 6+ messages in thread
From: linuxtestproject.agent @ 2026-11-04 11:42 UTC (permalink / raw)
To: Wenyuan Li; +Cc: ltp
Hi Wenyuan,
On Wed, Nov 4, 2026 at 7:00 PM, Wenyuan Li <2063309626@qq.com> wrote:
> lib: Validate sysconf() return values in the safe wrapper
Verdict - Reviewed
---
Note:
The agent can sometimes produce false positives although often its
findings are genuine. If you find issues with the review, please
comment this email or ignore the suggestions.
Regards,
LTP AI Reviewer
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2 1/2] lib: Validate sysconf() return values in the safe wrapper
2026-11-04 11:00 ` [LTP] [PATCH v2 1/2] lib: Validate sysconf() return values in the safe wrapper Wenyuan Li via ltp
2026-11-04 11:42 ` [LTP] " linuxtestproject.agent
@ 2026-11-04 12:28 ` Cyril Hrubis
1 sibling, 0 replies; 6+ messages in thread
From: Cyril Hrubis @ 2026-11-04 12:28 UTC (permalink / raw)
To: Wenyuan Li; +Cc: ltp
Hi!
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2 2/2] syscalls/madvise13: Check MADV_DONTNEED across an unmapped hole
2026-11-04 11:00 ` [LTP] [PATCH v2 2/2] syscalls/madvise13: Check MADV_DONTNEED across an unmapped hole Wenyuan Li via ltp
@ 2026-11-04 16:22 ` Cyril Hrubis
0 siblings, 0 replies; 6+ messages in thread
From: Cyril Hrubis @ 2026-11-04 16:22 UTC (permalink / raw)
To: Wenyuan Li; +Cc: ltp
Hi!
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
--
Cyril Hrubis
chrubis@suse.cz
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v2 0/2] Harden safe_sysconf() and add madvise13
[not found] <20261104110021.7870-1-2063309626@qq.com>
2026-11-04 11:00 ` [LTP] [PATCH v2 1/2] lib: Validate sysconf() return values in the safe wrapper Wenyuan Li via ltp
2026-11-04 11:00 ` [LTP] [PATCH v2 2/2] syscalls/madvise13: Check MADV_DONTNEED across an unmapped hole Wenyuan Li via ltp
@ 2026-11-11 12:00 ` Wenyuan Li via ltp
2 siblings, 0 replies; 6+ messages in thread
From: Wenyuan Li via ltp @ 2026-11-11 12:00 UTC (permalink / raw)
To: ltp
Hi,
A gentle ping on this series. Both patches were Reviewed-by Cyril on
Nov 4 and the CI checks came back green. I noticed they are not in
master yet (as of Nov 11, HEAD 0ee0ca54).
Is there anything blocking them, or anything you would like me to
change? I'm happy to rebase on current master if that helps.
Thanks,
Wenyuan Li
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-11-11 12:01 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20261104110021.7870-1-2063309626@qq.com>
2026-11-04 11:00 ` [LTP] [PATCH v2 1/2] lib: Validate sysconf() return values in the safe wrapper Wenyuan Li via ltp
2026-11-04 11:42 ` [LTP] " linuxtestproject.agent
2026-11-04 12:28 ` [LTP] [PATCH v2 1/2] " Cyril Hrubis
2026-11-04 11:00 ` [LTP] [PATCH v2 2/2] syscalls/madvise13: Check MADV_DONTNEED across an unmapped hole Wenyuan Li via ltp
2026-11-04 16:22 ` Cyril Hrubis
2026-11-11 12:00 ` [LTP] [PATCH v2 0/2] Harden safe_sysconf() and add madvise13 Wenyuan Li via ltp
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox