[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