[PATCH 12/13] mem: vma03: Rewrite to the new test library

Cyril Hrubis <[email protected]>
Newsgroups gmane.linux.ltp
Message-ID <[email protected]>
We also drop the __NR_mmap2 ifdef because the lapi/syscalls.h defines
the fallbacks to -1 when a syscall is not implemented on an achitecture,
so the macro is always defined.

Signed-off-by: Cyril Hrubis <[email protected]>
---
 testcases/kernel/mem/vma/vma03.c | 189 ++++++++++++-------------------
 1 file changed, 73 insertions(+), 116 deletions(-)

diff --git a/testcases/kernel/mem/vma/vma03.c b/testcases/kernel/mem/vma/vma03.c
index da1f5be99..7694e7e9a 100644
--- a/testcases/kernel/mem/vma/vma03.c
+++ b/testcases/kernel/mem/vma/vma03.c
@@ -1,149 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * Copyright (C) 2012 Red Hat, Inc.
+ * Copyright (C) 2026 Cyril Hrubis <[email protected]>
+ */
+
+/*\
+ * CVE-2011-2496 regression test.
  *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
+ * Verify that :manpage:`mremap(2)` correctly rejects an expansion that
+ * would cause the page-offset (pgoff) inside the mapping to wrap around
+ * due to overflow.
  *
- * This program is distributed in the hope that it would be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * The normal :manpage:`mmap(2)` paths all prevent creating a mapping
+ * whose pgoff could wrap, but an expanding :manpage:`mremap(2)` was
+ * able to take a valid mapping and grow it past the wrap boundary.
  *
- * Further, this software is distributed without any warranty that it
- * is free of the rightful claim of any third person regarding
- * infringement or the like.  Any license provided herein, whether
- * implied or otherwise, applies only to this software file.  Patent
- * licenses, if any, provided herein do not apply to combinations of
- * this program with other software, or any other product whatsoever.
+ * The test uses :manpage:`mmap2(2)` to create a file-backed mapping at
+ * a pgoff near ``ULONG_MAX``, then attempts to double its size with
+ * :manpage:`mremap(2)`. The kernel must reject this with ``EINVAL``.
  *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- * 02110-1301, USA.
- */
-/*
- * This is a reproducer for CVE-2011-2496.
- *
- * The normal mmap paths all avoid creating a mapping where the pgoff
- * inside the mapping could wrap around due to overflow.  However, an
- * expanding mremap() can take such a non-wrapping mapping and make it
- * bigger and cause a wrapping condition. There is also another case
- * where we expand mappings hiding in plain sight: the automatic stack
- * expansion.
- *
- * This program tries to remap a mapping with a new size that would
- * wrap pgoff. Notice that it only works on 32-bit arch for now.
+ * This test only runs on 32-bit systems with a 32-bit kernel because
+ * the overflow requires a 32-bit ``unsigned long`` address space.
  */
 
 #define _GNU_SOURCE
-#include "config.h"
-#include <sys/types.h>
 #include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/syscall.h>
-#include <errno.h>
-#include <fcntl.h>
 #include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
 
-#include "test.h"
-#include "tso_safe_macros.h"
-#include "tst_kernel.h"
+#include "tst_test.h"
 #include "lapi/abisize.h"
+#include "lapi/syscalls.h"
 
-char *TCID = "vma03";
-int TST_TOTAL = 1;
-
-#ifdef __NR_mmap2
 #define TESTFILE "testfile"
 
+static int fd = -1;
 static size_t pgsz;
-static int fd;
+static void *map = MAP_FAILED;
 
-static void *mmap2(void *addr, size_t length, int prot,
-		   int flags, int fd, off_t pgoffset);
-static void setup(void);
-static void cleanup(void);
-
-int main(int argc, char *argv[])
+static void setup(void)
 {
-	int lc;
-	void *map, *remap;
-	off_t pgoff;
-
-	if (TST_ABI != 32 || tst_kernel_bits() != 32) {
-		tst_brkm(TCONF, NULL,
-			 "test is designed for 32-bit system only.");
-	}
+	if (TST_ABI != 32 || tst_kernel_bits() != 32)
+		tst_brk(TCONF, "test is designed for 32-bit systems only");
 
-	tst_parse_opts(argc, argv, NULL, NULL);
-
-	pgsz = sysconf(_SC_PAGE_SIZE);
-	setup();
-
-	for (lc = 0; TEST_LOOPING(lc); lc++) {
-		tst_count = 0;
-
-		fd = SAFE_OPEN(NULL, TESTFILE, O_RDWR);
-
-		/*
-		 * The pgoff is counted in 4K units and must be page-aligned,
-		 * hence we must align it down to page_size/4096 in a case that
-		 * the system has page_size > 4K.
-		 */
-		pgoff = (ULONG_MAX - 1)&(~((pgsz-1)>>12));
-		map = mmap2(NULL, pgsz, PROT_READ | PROT_WRITE, MAP_PRIVATE,
-			    fd, pgoff);
-		if (map == MAP_FAILED)
-			tst_brkm(TBROK | TERRNO, cleanup, "mmap2");
-
-		remap = mremap(map, pgsz, 2 * pgsz, 0);
-		if (remap == MAP_FAILED) {
-			if (errno == EINVAL)
-				tst_resm(TPASS, "mremap failed as expected.");
-			else
-				tst_resm(TFAIL | TERRNO, "mremap");
-			munmap(map, pgsz);
-		} else {
-			tst_resm(TFAIL, "mremap succeeded unexpectedly.");
-			munmap(remap, 2 * pgsz);
-		}
-
-		close(fd);
-	}
+	pgsz = getpagesize();
 
-	cleanup();
-	tst_exit();
+	SAFE_CREAT(TESTFILE, 0644);
 }
 
-static void *mmap2(void *addr, size_t length, int prot,
-		   int flags, int fd, off_t pgoffset)
+static void run(void)
 {
-	return (void *)syscall(SYS_mmap2, addr, length, prot,
-			       flags, fd, pgoffset);
-}
+	/*
+	 * pgoff is counted in 4K units, must be page-aligned, so
+	 * align down to page_size/4096 for systems with page_size > 4K.
+	 */
+	off_t pgoff = (ULONG_MAX - 1) & (~((pgsz - 1) >> 12));
 
-static void setup(void)
-{
-	tst_sig(FORK, DEF_HANDLER, cleanup);
+	fd = SAFE_OPEN(TESTFILE, O_RDWR);
+
+	map = (void *)tst_syscall(__NR_mmap2, NULL, pgsz,
+				  PROT_READ | PROT_WRITE,
+				  MAP_PRIVATE, fd, pgoff);
+
+	if (map == MAP_FAILED) {
+		tst_brk(TBROK | TERRNO, "mmap2(%s, pgoff=%ld)",
+			TESTFILE, (long)pgoff);
+	}
+
+	void *remap = mremap(map, pgsz, 2 * pgsz, 0);
 
-	tst_tmpdir();
+	if (remap == MAP_FAILED) {
+		if (errno == EINVAL)
+			tst_res(TPASS, "mremap() failed with EINVAL as expected");
+		else
+			tst_res(TFAIL | TERRNO, "mremap() failed unexpectedly");
 
-	fd = SAFE_CREAT(NULL, TESTFILE, 0644);
-	close(fd);
+		SAFE_MUNMAP(map, pgsz);
+	} else {
+		tst_res(TFAIL, "mremap() succeeded unexpectedly");
+		SAFE_MUNMAP(remap, 2 * pgsz);
+	}
 
-	TEST_PAUSE;
+	map = MAP_FAILED;
+	SAFE_CLOSE(fd);
 }
 
 static void cleanup(void)
 {
-	tst_rmdir();
-}
-#else /* __NR_mmap2 */
-int main(int argc, char *argv[])
-{
-	tst_brkm(TCONF, NULL, "__NR_mmap2 is not defined on your system");
+	if (map != MAP_FAILED)
+		SAFE_MUNMAP(map, pgsz);
+
+	if (fd != -1)
+		SAFE_CLOSE(fd);
 }
-#endif
+
+static struct tst_test test = {
+	.test_all = run,
+	.setup = setup,
+	.cleanup = cleanup,
+	.needs_tmpdir = 1,
+	.tags = (const struct tst_tag[]) {
+		{"linux-git", "982134ba6261"},
+		{"CVE", "2011-2496"},
+		{}
+	}
+};
-- 
2.53.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.