* [LTP] [PATCH 0/5] Rewrite mremap testing suite
@ 2026-07-21 12:41 Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 1/5] mremap01: Convert to new API Andrea Cervesato
` (4 more replies)
0 siblings, 5 replies; 7+ messages in thread
From: Andrea Cervesato @ 2026-07-21 12:41 UTC (permalink / raw)
To: Linux Test Project
This rewrite has been done using multi-agent configuration that is now
present in ltp-agent project.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
Andrea Cervesato (5):
mremap01: Convert to new API
mremap02: Convert to new API
mremap03: Convert to new API
mremap04: Convert to new API
mremap05: Convert to new API
testcases/kernel/syscalls/mremap/Makefile | 4 +-
testcases/kernel/syscalls/mremap/mremap01.c | 281 ++++++++-----------------
testcases/kernel/syscalls/mremap/mremap02.c | 197 ++++-------------
testcases/kernel/syscalls/mremap/mremap03.c | 203 +++---------------
testcases/kernel/syscalls/mremap/mremap04.c | 268 +++++------------------
testcases/kernel/syscalls/mremap/mremap05.c | 315 +++++++++++-----------------
6 files changed, 337 insertions(+), 931 deletions(-)
---
base-commit: 34388e7008c8da9a9cccd62411cdd6ea7cf33c8b
change-id: 20260720-rewrite_mremap_testing_suite-da09a8bc836a
Best regards,
--
Andrea Cervesato <andrea.cervesato@suse.com>
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 7+ messages in thread
* [LTP] [PATCH 1/5] mremap01: Convert to new API
2026-07-21 12:41 [LTP] [PATCH 0/5] Rewrite mremap testing suite Andrea Cervesato
@ 2026-07-21 12:41 ` Andrea Cervesato
2026-07-21 13:53 ` [LTP] " linuxtestproject.agent
2026-07-21 12:41 ` [LTP] [PATCH 2/5] mremap02: " Andrea Cervesato
` (3 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Andrea Cervesato @ 2026-07-21 12:41 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Convert the test to the new LTP API (tst_test.h) using a semantic
rewrite. The test verifies that mremap() with MREMAP_MAYMOVE can grow a
file-backed MAP_SHARED mapping, that the grown region is fully usable,
and that its contents synchronize to the backing file via msync().
The mapping work is performed per-iteration so that '-i' runs always
grow a freshly created mapping instead of an already-grown one.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mremap/mremap01.c | 281 +++++++++-------------------
1 file changed, 85 insertions(+), 196 deletions(-)
diff --git a/testcases/kernel/syscalls/mremap/mremap01.c b/testcases/kernel/syscalls/mremap/mremap01.c
index 8c241d45cb7b6127ea7cc25a519c73011b6ea7bc..2cb21835246bb32c59b1e2dd5b6041ae93a6aada 100644
--- a/testcases/kernel/syscalls/mremap/mremap01.c
+++ b/testcases/kernel/syscalls/mremap/mremap01.c
@@ -1,237 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (c) Linux Test Project, 2026
*/
-/*
- * Test Name: mremap01
- *
- * Test Description:
- * Verify that, mremap() succeeds when used to expand the existing
- * virtual memory mapped region to the requested size where the
- * virtual memory area was previously mapped to a file using mmap().
+/*\
+ * Verify that :manpage:`mremap(2)` succeeds when used to expand an existing
+ * virtual memory region that was previously mapped to a file with
+ * :manpage:`mmap(2)`.
*
- * Expected Result:
- * mremap() should succeed returning the address of new virtual memory area.
- * The expanded mapped memory region should be accessible and able to
- * synchronize with the file.
+ * After growing the mapping with ``MREMAP_MAYMOVE``, the expanded region must
+ * be fully accessible and its contents must synchronize to the backing file
+ * with :manpage:`msync(2)`.
*
- * Algorithm:
- * Setup:
- * Setup signal handling.
- * Create temporary directory.
- * Pause for SIGUSR1 if option specified.
+ * [Algorithm]
*
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * Log the errno and Issue a FAIL message.
- * Otherwise,
- * Verify the Functionality of system call
- * if successful,
- * Issue Functionality-Pass message.
- * Otherwise,
- * Issue Functionality-Fail message.
- * Cleanup:
- * Print errno log and/or timing stats if options given
- * Delete the temporary directory created.
- *
- * Usage: <for command-line>
- * mremap01 [-c n] [-f] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -f : Turn off functionality Testing.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * 11/09/2001 Manoj Iyer (manjo@austin.ibm.com)
- * Modified.
- * - #include <linux/mman.h> should not be included as per man page for
- * mremap, #include <sys/mman.h> alone should do the job. But inorder
- * to include definition of MREMAP_MAYMOVE defined in bits/mman.h
- * (included by sys/mman.h) __USE_GNU needs to be defined.
- * There may be a more elegant way of doing this...
- *
- * RESTRICTIONS:
- * None.
+ * - create a temporary file and stretch it to the initial mapping size
+ * - map the file with ``MAP_SHARED`` and ``PROT_WRITE``
+ * - stretch the file to the new (larger) size before growing the mapping
+ * - grow the mapping with mremap() and ``MREMAP_MAYMOVE``
+ * - write every byte of the grown region to prove it is usable
+ * - synchronize the region to the backing file with ``MS_SYNC``
+ * - read the data back from the backing file to prove it was synchronized
*/
#define _GNU_SOURCE
-#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
-#include <fcntl.h>
-
-#include "test.h"
-#include "tso_safe_macros.h"
+#include "tst_test.h"
+#include "tst_safe_prw.h"
#define TEMPFILE "mremapfile"
-char *TCID = "mremap01";
-int TST_TOTAL = 1;
-char *addr; /* addr of memory mapped region */
-int memsize; /* memory mapped size */
-int newsize; /* new size of virtual memory block */
-int fildes; /* file descriptor for tempfile */
-
-void setup(); /* Main setup function of test */
-void cleanup(); /* cleanup function for the test */
+static char *addr = MAP_FAILED;
+static size_t memsize;
+static size_t newsize;
+static int fildes = -1;
-int main(int ac, char **av)
+static void setup(void)
{
- int ind; /* counter variable */
+ int pagesz = getpagesize();
- tst_parse_opts(ac, av, NULL, NULL);
+ memsize = 1000 * pagesz;
+ newsize = memsize * 2;
- tst_count = 0;
+ fildes = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);
+}
- setup();
+static int verify_file(void)
+{
+ size_t offsets[3];
+ unsigned int i;
+ char got;
- /*
- * Call mremap to expand the existing mapped
- * memory region (memsize) by newsize limits.
- */
- addr = mremap(addr, memsize, newsize, MREMAP_MAYMOVE);
+ offsets[0] = 0;
+ offsets[1] = newsize / 2;
+ offsets[2] = newsize - 1;
- /* Check for the return value of mremap() */
- if (addr == MAP_FAILED)
- tst_brkm(TFAIL | TERRNO, cleanup, "mremap failed");
+ for (i = 0; i < ARRAY_SIZE(offsets); i++) {
+ size_t off = offsets[i];
- /*
- * Attempt to initialize the expanded memory
- * mapped region with data. If the map area
- * was bad, we'd get SIGSEGV.
- */
- for (ind = 0; ind < newsize; ind++) {
- addr[ind] = (char)ind;
- }
+ SAFE_PREAD(1, fildes, &got, 1, (off_t)off);
- /*
- * Memory mapped area is good. Now, attempt
- * to synchronize the mapped memory region
- * with the file.
- */
- if (msync(addr, newsize, MS_SYNC) != 0) {
- tst_resm(TFAIL | TERRNO, "msync failed to synch "
- "mapped file");
- } else {
- tst_resm(TPASS, "Functionality of "
- "mremap() is correct");
+ if (got != (char)off) {
+ tst_res(TFAIL, "file[%zu] == 0x%02x, expected 0x%02x",
+ off, (unsigned char)got, (unsigned char)off);
+ return 1;
+ }
}
- cleanup();
- tst_exit();
+ return 0;
}
-/*
- * void
- * setup() - performs all ONE TIME setup for this test.
- *
- * Get system page size, Set the size of virtual memory area and the
- * new size after resize,
- * Creat a temporary directory and a file under it.
- * Stratch the file size to the size of virtual memory area and
- * write 1 byte (\0). Map the temporary file for the length of virtual
- * memory (memsize) into memory.
- */
-void setup(void)
+static void run(void)
{
- int pagesz; /* system's page size */
-
- tst_sig(NOFORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /* Get the system page size */
- if ((pagesz = getpagesize()) < 0) {
- tst_brkm(TFAIL, NULL,
- "getpagesize failed to get system page size");
- }
+ size_t ind;
- /* Get the size of virtual memory area to be mapped */
- memsize = (1000 * pagesz);
-
- /* Get the New size of virtual memory block after resize */
- newsize = (memsize * 2);
-
- tst_tmpdir();
+ /*
+ * Establish a fresh memsize mapping for every iteration so mremap()
+ * always grows a newly created mapping instead of an already-grown one.
+ */
+ SAFE_LSEEK(fildes, (off_t)memsize, SEEK_SET);
+ SAFE_WRITE(SAFE_WRITE_ALL, fildes, "\0", 1);
- /* Creat a temporary file used for mapping */
- if ((fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666)) < 0)
- tst_brkm(TBROK | TERRNO, cleanup, "opening %s failed",
- TEMPFILE);
+ addr = SAFE_MMAP(0, memsize, PROT_READ | PROT_WRITE, MAP_SHARED,
+ fildes, 0);
- /* Stretch the file to the size of virtual memory area */
- if (lseek(fildes, (off_t) memsize, SEEK_SET) != (off_t) memsize) {
- tst_brkm(TBROK | TERRNO, cleanup,
- "lseeking to %d offset pos. failed", memsize);
- }
+ SAFE_LSEEK(fildes, (off_t)newsize, SEEK_SET);
+ SAFE_WRITE(SAFE_WRITE_ALL, fildes, "\0", 1);
- /* Write one byte data into temporary file */
- if (write(fildes, "\0", 1) != 1) {
- tst_brkm(TBROK, cleanup, "writing to %s failed", TEMPFILE);
- }
+ TESTPTR(mremap(addr, memsize, newsize, MREMAP_MAYMOVE));
+ addr = TST_RET_PTR;
+ if (addr == MAP_FAILED)
+ tst_brk(TFAIL | TTERRNO, "mremap failed");
- /*
- * Call mmap to map virtual memory (memsize bytes) from the
- * beginning of temporary file (offset is 0) into memory.
- */
- addr = mmap(0, memsize, PROT_WRITE, MAP_SHARED, fildes, 0);
+ for (ind = 0; ind < newsize; ind++)
+ addr[ind] = (char)ind;
- /* Check for the return value of mmap() */
- if (addr == (char *)MAP_FAILED) {
- tst_brkm(TBROK, cleanup, "mmaping Failed on %s", TEMPFILE);
- }
+ SAFE_MSYNC(addr, newsize, MS_SYNC);
- /* Stretch the file to newsize of virtual memory block */
- if (lseek(fildes, (off_t) newsize, SEEK_SET) != (off_t) newsize) {
- tst_brkm(TBROK, cleanup, "lseek() to %d offset pos. Failed, "
- "error=%d : %s", newsize, errno, strerror(errno));
- }
+ if (verify_file())
+ tst_res(TFAIL, "mremap()'d region did not sync to the file");
+ else
+ tst_res(TPASS, "Functionality of mremap() is correct");
- /* Write one byte data into temporary file */
- if (write(fildes, "\0", 1) != 1) {
- tst_brkm(TBROK | TERRNO, cleanup, "writing to %s failed",
- TEMPFILE);
- }
+ SAFE_MUNMAP(addr, newsize);
+ addr = MAP_FAILED;
}
-/*
- * void
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- * Unmap the mapped memory area done in the test.
- * Close the temporary file.
- * Remove the temporary directory.
- */
-void cleanup(void)
+static void cleanup(void)
{
+ if (addr != MAP_FAILED)
+ SAFE_MUNMAP(addr, newsize);
- /* Unmap the mapped memory */
- if (munmap(addr, newsize) != 0)
- tst_brkm(TBROK | TERRNO, NULL, "munmap failed");
-
- /* Close the temporary file */
- SAFE_CLOSE(NULL, fildes);
-
- tst_rmdir();
+ if (fildes != -1)
+ SAFE_CLOSE(fildes);
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+ .needs_tmpdir = 1,
+};
--
2.51.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [LTP] [PATCH 2/5] mremap02: Convert to new API
2026-07-21 12:41 [LTP] [PATCH 0/5] Rewrite mremap testing suite Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 1/5] mremap01: Convert to new API Andrea Cervesato
@ 2026-07-21 12:41 ` Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 3/5] mremap03: " Andrea Cervesato
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Andrea Cervesato @ 2026-07-21 12:41 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Convert the mremap02 test case from the legacy LTP API to the new
tst_test API.
Rewrite the test to explicitly construct a genuinely non-page-aligned
old_address by mapping a single anonymous page and offsetting it by one
byte, replacing the original's reliance on an uninitialized global
pointer. Use TST_EXP_FAIL_PTR_VOID() to verify that mremap() fails with
MAP_FAILED and EINVAL when expanding the mapping.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mremap/mremap02.c | 197 ++++++----------------------
1 file changed, 40 insertions(+), 157 deletions(-)
diff --git a/testcases/kernel/syscalls/mremap/mremap02.c b/testcases/kernel/syscalls/mremap/mremap02.c
index 2dabc68472a2686a83b7ab7bb2fdd92611a6e8de..7fe699285325748ac3ed985585a2fd7afc348fba 100644
--- a/testcases/kernel/syscalls/mremap/mremap02.c
+++ b/testcases/kernel/syscalls/mremap/mremap02.c
@@ -1,178 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * 11/2001 Modified by Manoj Iyer <manjo@austin.ibm.com>
+ * Copyright (c) Linux Test Project, 2026
*/
-/*
- * Test Name: mremap02
- *
- * Test Description:
- * Verify that,
- * mremap() fails when used to expand the existing virtual memory mapped
- * region to the requested size, if the virtual memory area previously
- * mapped was not page aligned or invalid argument specified.
- *
- * Expected Result:
- * mremap() should return -1 and set errno to EINVAL.
- *
- * Algorithm:
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * if errno set == expected errno
- * Issue sys call fails with expected return value and errno.
- * Otherwise,
- * Issue sys call fails with unexpected errno.
- * Otherwise,
- * Issue sys call returns unexpected value.
+/*\
+ * Verify that :manpage:`mremap(2)` fails with errno ``EINVAL`` when it is used
+ * to expand an existing mapping while the passed ``old_address`` is not page
+ * aligned.
*
- * Cleanup:
- * Print errno log and/or timing stats if options given
+ * [Algorithm]
*
- * Usage: <for command-line>
- * mremap02 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -p x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * 11/09/2001 Manoj Iyer (manjo@austin.ibm.com)
- * Modified.
- * - #include <linux/mman.h> should not be included as per man page for
- * mremap, #include <sys/mman.h> alone should do the job. But inorder
- * to include definition of MREMAP_MAYMOVE defined in bits/mman.h
- * (included by sys/mman.h) __USE_GNU needs to be defined.
- * There may be a more elegant way of doing this...
- *
- *
- * RESTRICTIONS:
- * None.
+ * - Map a single anonymous page.
+ * - Call mremap() to grow it to two pages with ``MREMAP_MAYMOVE``, passing a
+ * deliberately misaligned ``old_address`` (mapping start + 1 byte).
+ * - Expect the call to fail with ``MAP_FAILED`` and ``EINVAL``.
*/
+
#define _GNU_SOURCE
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
#include <sys/mman.h>
+#include "tst_test.h"
-#include "test.h"
+static long page_size;
+static size_t new_size;
+static void *page;
+static void *bad_addr;
-char *TCID = "mremap02";
-int TST_TOTAL = 1;
-char *addr; /* addr of memory mapped region */
-int memsize; /* memory mapped size */
-int newsize; /* new size of virtual memory block */
-
-void setup(); /* Main setup function of test */
-void cleanup(); /* cleanup function for the test */
-
-int main(int ac, char **av)
+static void setup(void)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
+ page_size = getpagesize();
+ new_size = page_size * 2;
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Attempt to expand the existing mapped
- * memory region (memsize) by newsize limits using
- * mremap() should fail as old virtual address is not
- * page aligned.
- */
- errno = 0;
- addr = mremap(addr, memsize, newsize, MREMAP_MAYMOVE);
- TEST_ERRNO = errno;
-
- /* Check for the return value of mremap() */
- if (addr != MAP_FAILED) {
- tst_resm(TFAIL,
- "mremap returned invalid value, expected: -1");
-
- /* Unmap the mapped memory region */
- if (munmap(addr, newsize) != 0) {
- tst_brkm(TBROK, cleanup, "munmap fails to "
- "unmap the expanded memory region, "
- "error=%d", errno);
- }
- continue;
- }
-
- if (errno == EINVAL) {
- tst_resm(TPASS, "mremap() Failed, 'invalid argument "
- "specified' - errno %d", TEST_ERRNO);
- } else {
- tst_resm(TFAIL, "mremap() Failed, "
- "'Unexpected errno %d", TEST_ERRNO);
- }
- }
-
- cleanup();
- tst_exit();
+ page = SAFE_MMAP(NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ /* Force a non-page-aligned old_address, the invalid argument. */
+ bad_addr = (char *)page + 1;
}
-/*
- * setup() - performs all ONE TIME setup for this test.
- *
- * Get system page size, Set the size of virtual memory area and the
- * new size after resize, Set the virtual memory address such that it
- * is not aligned.
- */
-void setup(void)
+static void run(void)
{
+ TST_EXP_FAIL_PTR_VOID(mremap(bad_addr, page_size, new_size,
+ MREMAP_MAYMOVE), EINVAL);
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /* Get the system page size */
- if ((memsize = getpagesize()) < 0) {
- tst_brkm(TFAIL, NULL,
- "getpagesize() fails to get system page size");
- }
-
- /* Get the New size of virtual memory block after resize */
- newsize = (memsize * 2);
-
- /* Set the old virtual memory address */
- addr = (char *)(addr + (memsize - 1));
+ if (TST_RET_PTR != MAP_FAILED)
+ SAFE_MUNMAP(TST_RET_PTR, new_size);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
{
-
- /* Exit the program */
-
+ SAFE_MUNMAP(page, page_size);
}
+
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+};
--
2.51.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [LTP] [PATCH 3/5] mremap03: Convert to new API
2026-07-21 12:41 [LTP] [PATCH 0/5] Rewrite mremap testing suite Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 1/5] mremap01: Convert to new API Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 2/5] mremap02: " Andrea Cervesato
@ 2026-07-21 12:41 ` Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 4/5] mremap04: " Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 5/5] mremap05: " Andrea Cervesato
4 siblings, 0 replies; 7+ messages in thread
From: Andrea Cervesato @ 2026-07-21 12:41 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Convert the mremap03 test case from the legacy LTP API to the new
tst_test API.
Rewrite the test to use TST_EXP_FAIL_PTR_VOID() to verify that
mremap() fails with MAP_FAILED and EFAULT when growing a mapping
whose old_address refers to an unmapped region obtained via
tst_get_bad_addr().
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mremap/mremap03.c | 203 +++++-----------------------
1 file changed, 34 insertions(+), 169 deletions(-)
diff --git a/testcases/kernel/syscalls/mremap/mremap03.c b/testcases/kernel/syscalls/mremap/mremap03.c
index 02b79bc47bba0ac576182c00711ff2296aaeaf65..6003657d452ce022daeeb5d54a967cf5b69b6248 100644
--- a/testcases/kernel/syscalls/mremap/mremap03.c
+++ b/testcases/kernel/syscalls/mremap/mremap03.c
@@ -1,187 +1,52 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * 11/2001 Modified by Manoj Iyer <manjo@austin.ibm.com>
+ * Copyright (c) Linux Test Project, 2026
*/
-/*
- * Test Name: mremap03
- *
- * Test Description:
- * Verify that,
- * mremap() fails when used to expand the existing virtual memory mapped
- * region to the requested size, if there already exists mappings that
- * cover the whole address space requsted or the old address specified was
- * not mapped.
- *
- * Expected Result:
- * mremap() should return -1 and set errno to EFAULT.
- *
- * Algorithm:
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * if errno set == expected errno
- * Issue sys call fails with expected return value and errno.
- * Otherwise,
- * Issue sys call fails with unexpected errno.
- * Otherwise,
- * Issue sys call returns unexpected value.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
+/*\
+ * Verify that :manpage:`mremap(2)` fails with errno ``EFAULT`` when it is used
+ * to expand a mapping whose ``old_address`` refers to a region that is not
+ * mapped.
*
- * Usage: <for command-line>
- * mremap03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -p x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
+ * [Algorithm]
*
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * 11/09/2001 Manoj Iyer (manjo@austin.ibm.com)
- * Modified.
- * - #include <linux/mman.h> should not be included as per man page for
- * mremap, #include <sys/mman.h> alone should do the job. But inorder
- * to include definition of MREMAP_MAYMOVE defined in bits/mman.h
- * (included by sys/mman.h) __USE_GNU needs to be defined.
- * There may be a more elegant way of doing this...
- *
- *
- * RESTRICTIONS:
- * None.
+ * - Obtain an unmapped address via ``tst_get_bad_addr()``.
+ * - Call mremap() to grow it to twice its size with ``MREMAP_MAYMOVE``,
+ * passing the unmapped ``old_address``.
+ * - Expect the call to fail with ``MAP_FAILED`` and ``EFAULT``.
*/
+
#define _GNU_SOURCE
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
#include <sys/mman.h>
+#include "tst_test.h"
-#include "test.h"
-
-char *TCID = "mremap03";
-int TST_TOTAL = 1;
-static char *bad_addr;
-static char *addr; /* addr of memory mapped region */
-int memsize; /* memory mapped size */
-int newsize; /* new size of virtual memory block */
+static long page_size;
+static size_t memsize;
+static size_t newsize;
+static void *bad_addr;
-void setup(); /* Main setup function of test */
-void cleanup(); /* cleanup function for the test */
-
-int main(int ac, char **av)
+static void setup(void)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Attempt to expand the existing mapped
- * memory region (memsize) by newsize limits
- * using mremap() should fail as specified old
- * virtual address was not mapped.
- */
- errno = 0;
- addr = mremap(bad_addr, memsize, newsize, MREMAP_MAYMOVE);
- TEST_ERRNO = errno;
-
- /* Check for the return value of mremap() */
- if (addr != MAP_FAILED) {
- tst_resm(TFAIL,
- "mremap returned invalid value, expected: -1");
-
- /* Unmap the mapped memory region */
- if (munmap(addr, newsize) != 0) {
- tst_brkm(TFAIL, cleanup, "munmap fails to "
- "unmap the expanded memory region, "
- " error=%d", errno);
- }
- continue;
- }
-
- /* Check for the expected errno */
- if (errno == EFAULT) {
- tst_resm(TPASS, "mremap() Fails, 'old region not "
- "mapped', errno %d", TEST_ERRNO);
- } else {
- tst_resm(TFAIL, "mremap() Fails, "
- "'Unexpected errno %d", TEST_ERRNO);
- }
- }
-
- cleanup();
- tst_exit();
+ page_size = getpagesize();
+ memsize = 1000 * page_size;
+ newsize = 2 * memsize;
+ bad_addr = tst_get_bad_addr(NULL);
}
-/*
- * setup() - performs all ONE TIME setup for this test.
- *
- * Get system page size.
- * Set the old address point some high address which is not mapped.
- */
-void setup(void)
+static void run(void)
{
- int page_sz; /* system page size */
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
+ TST_EXP_FAIL_PTR_VOID(mremap(bad_addr, memsize, newsize,
+ MREMAP_MAYMOVE), EFAULT);
- /* Get the system page size */
- if ((page_sz = getpagesize()) < 0) {
- tst_brkm(TFAIL, NULL,
- "getpagesize() fails to get system page size");
- }
-
- /* Get the size of virtual memory area to be mapped */
- memsize = (1000 * page_sz);
-
- /* Get the New size of virtual memory block after resize */
- newsize = (memsize * 2);
-
- /*
- * Set the old virtual address point to some address
- * which is not mapped.
- */
- bad_addr = tst_get_bad_addr(cleanup);
+ if (TST_RET_PTR != MAP_FAILED)
+ SAFE_MUNMAP(TST_RET_PTR, newsize);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
-{
-
- /* Exit the program */
-
-}
+static struct tst_test test = {
+ .setup = setup,
+ .test_all = run,
+};
--
2.51.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [LTP] [PATCH 4/5] mremap04: Convert to new API
2026-07-21 12:41 [LTP] [PATCH 0/5] Rewrite mremap testing suite Andrea Cervesato
` (2 preceding siblings ...)
2026-07-21 12:41 ` [LTP] [PATCH 3/5] mremap03: " Andrea Cervesato
@ 2026-07-21 12:41 ` Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 5/5] mremap05: " Andrea Cervesato
4 siblings, 0 replies; 7+ messages in thread
From: Andrea Cervesato @ 2026-07-21 12:41 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Convert the mremap04 test case from the legacy LTP API to the new
tst_test API.
Rewrite the test to use TST_EXP_FAIL_PTR_VOID() to verify that
mremap() fails with MAP_FAILED and ENOMEM when growing an existing
SysV shared memory mapping in place (old_size=1 page, new_size=2
pages, flags=0, no MREMAP_MAYMOVE) beyond what can be expanded at
its current virtual address.
Switch the Makefile from libltpipc to libltpnewipc, since the
new-API test now relies on GETIPCKEY() from tse_newipc.h.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mremap/Makefile | 4 +-
testcases/kernel/syscalls/mremap/mremap04.c | 268 +++++-----------------------
2 files changed, 51 insertions(+), 221 deletions(-)
diff --git a/testcases/kernel/syscalls/mremap/Makefile b/testcases/kernel/syscalls/mremap/Makefile
index 8811b887e34ff4aa8e372548e10006621cb3ad07..4c8990ea8257f7b96334c312a906ba6cb3814501 100644
--- a/testcases/kernel/syscalls/mremap/Makefile
+++ b/testcases/kernel/syscalls/mremap/Makefile
@@ -3,11 +3,11 @@
top_srcdir ?= ../../../..
-LTPLIBS = ipc
+LTPLIBS = newipc
include $(top_srcdir)/include/mk/testcases.mk
-mremap04: LTPLDLIBS = -lltpipc
+mremap04: LTPLDLIBS = -lltpnewipc
mremap07: LDLIBS += -lpthread
include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/mremap/mremap04.c b/testcases/kernel/syscalls/mremap/mremap04.c
index 53902df73f0ed177acfa064e7e15c1f9f321c9d2..fd8b8255b7de574db22a9d228d15c9637ba7efc4 100644
--- a/testcases/kernel/syscalls/mremap/mremap04.c
+++ b/testcases/kernel/syscalls/mremap/mremap04.c
@@ -1,245 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
- *
- * Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * Copyright (c) International Business Machines Corp., 2001
+ * 07/2001 Ported by Wayne Boyer
+ * 11/2001 Modified by Manoj Iyer <manjo@austin.ibm.com>
+ * 02/2008 Modified by Renaud Lottiaux <Renaud.Lottiaux@kerlabs.com>
+ * Copyright (c) Linux Test Project, 2026
*/
-/*
- * Test Name: mremap04
- *
- * Test Description:
- * Verify that,
- * mremap() fails when used to expand the existing virtual memory mapped
- * region to the requested size, if the memory area cannot be expanded at
- * the current virtual address and MREMAP_MAYMOVE flag not set.
- *
- * Expected Result:
- * mremap() should return -1 and set errno to ENOMEM.
- *
- * Algorithm:
- * Setup:
- * Setup signal handling.
- * Create temporary directory.
- * Pause for SIGUSR1 if option specified.
- *
- * Test:
- * Loop if the proper options are given.
- * Execute system call
- * Check return code, if system call failed (return=-1)
- * if errno set == expected errno
- * Issue sys call failed with expected return value and errno.
- * Otherwise,
- * Issue sys call failed with unexpected errno.
- * Otherwise,
- * Issue sys call returns unexpected value.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
- * Delete the temporary directory(s)/file(s) created.
- *
- * Usage: <for command-line>
- * mremap04 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -p x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * 11/09/2001 Manoj Iyer (manjo@austin.ibm.com)
- * Modified.
- * - #include <linux/mman.h> should not be included as per man page for
- * mremap, #include <sys/mman.h> alone should do the job. But inorder
- * to include definition of MREMAP_MAYMOVE defined in bits/mman.h
- * (included by sys/mman.h) __USE_GNU needs to be defined.
- * There may be a more elegant way of doing this...
+/*\
+ * Verify that :manpage:`mremap(2)` fails with errno ``ENOMEM`` when it is used
+ * to expand an existing mapping in place, if the region cannot be expanded at
+ * the current virtual address and the ``MREMAP_MAYMOVE`` flag is not set.
*
- * 26/02/2008 Renaud Lottiaux (Renaud.Lottiaux@kerlabs.com)
- * - Fix concurrency issue. Use a shm key from getipckey instead of
- * a fixed hard-coded value.
+ * [Algorithm]
*
- * RESTRICTIONS:
- * None.
+ * - create a SysV shared memory segment of two pages and attach it with
+ * :manpage:`shmat(2)`
+ * - call mremap() on the attached address to grow it from one page to two
+ * pages with ``flags`` set to 0 (no ``MREMAP_MAYMOVE``)
+ * - expect the call to fail with ``MAP_FAILED`` and ``ENOMEM``
*/
+
#define _GNU_SOURCE
-#include <errno.h>
-#include <unistd.h>
#include <sys/mman.h>
#include <sys/ipc.h>
#include <sys/shm.h>
+#include "tst_test.h"
+#include "tse_newipc.h"
+#include "tst_safe_sysv_ipc.h"
-#include "test.h"
-
-#define SHM_MODE (SHM_R | SHM_W) /* mode permissions of shared memory */
-
-char *TCID = "mremap04";
-int TST_TOTAL = 1;
-char *addr; /* addr of memory mapped region */
-char *shmaddr; /* pointer to shared memory segment */
-int shmid; /* shared memory identifier. */
-int memsize; /* memory mapped size */
-int newsize; /* new size of virtual memory block */
-
-void setup(); /* Main setup function of test */
-void cleanup(); /* cleanup function for the test */
+static char *shmaddr;
+static int shmid = -1;
+static size_t memsize;
+static size_t newsize;
-extern int getipckey();
-
-int main(int ac, char **av)
+static void setup(void)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Attempt to expand the existing shared
- * memory region of newsize by newsize limits
- * using mremap() should fail as specified
- * memory area already locked and MREMAP_MAYMOVE
- * flag unset.
- */
- errno = 0;
- addr = mremap(shmaddr, memsize, newsize, 0);
- TEST_ERRNO = errno;
-
- /* Check for the return value of mremap() */
- if (addr != MAP_FAILED) {
- tst_resm(TFAIL,
- "mremap returned invalid value, expected: -1");
-
- /* Unmap the mapped memory region */
- if (munmap(addr, newsize) != 0) {
- tst_brkm(TFAIL, cleanup, "munmap failed to "
- "unmap the expanded memory region, "
- "error=%d", errno);
- }
- continue;
- }
-
- if (TEST_ERRNO == ENOMEM) {
- tst_resm(TPASS, "mremap() failed, "
- "'MREMAP_MAYMOVE flag unset', "
- "errno %d", TEST_ERRNO);
- } else {
- tst_resm(TFAIL, "mremap() failed, "
- "Unexpected errno %d", TEST_ERRNO);
- }
- }
+ key_t shmkey;
- cleanup();
- tst_exit();
+ memsize = getpagesize();
+ newsize = memsize * 2;
+ shmkey = GETIPCKEY();
+ shmid = SAFE_SHMGET(shmkey, newsize, IPC_CREAT | SHM_RW);
+ shmaddr = SAFE_SHMAT(shmid, NULL, 0);
}
-/*
- * setup() - performs all ONE TIME setup for this test.
- *
- * Get system page size, Set the size of virtual memory area and the
- * newsize after resize,
- * Create a named shared memory segment SHMKEY of newsize and mode SHM_MODE
- * by using shmget() which returns a shared memory identifier associated
- * with the created shared memory segment.
- * Call shmat() to attach the shared memory segment to the data segment of the
- * calling process. The segment is attached at the first available address as
- * selected by the system.
- */
-void setup(void)
+static void run(void)
{
- key_t shmkey;
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- tst_tmpdir();
-
- /* Get the system page size */
- if ((memsize = getpagesize()) < 0) {
- tst_brkm(TBROK, NULL,
- "getpagesize() failed to get system page size");
- }
-
- /* Get the New size of virtual memory block after resize */
- newsize = (memsize * 2);
-
- /* get an IPC resource key */
- shmkey = getipckey();
-
/*
- * Create a shared memory segment represented by SHMKEY of
- * specified size 'newsize' and mode permissions 'SHM_MODE'.
+ * Pass old_size of one page while the segment is two pages: the
+ * mismatch is intentional and must be preserved.
*/
- shmid = shmget(shmkey, newsize, IPC_CREAT | SHM_MODE);
- if (shmid == -1) {
- tst_brkm(TBROK, NULL, "shmget() Failed to create a shared "
- "memory, error:%d", errno);
- }
+ TST_EXP_FAIL_PTR_VOID(mremap(shmaddr, memsize, newsize, 0), ENOMEM);
- /*
- * Attach the shared memory segment associated with the shared
- * memory identifier specified by "shmid" to the data segment of
- * the calling process at the first available address as selected
- * by the system.
- */
- shmaddr = shmat(shmid, NULL, 0);
- if (shmaddr == (void *)-1) {
- tst_brkm(TBROK, cleanup, "shmat() Failed to attach shared "
- "memory, error:%d", errno);
- }
+ if (TST_RET_PTR != MAP_FAILED)
+ SAFE_MUNMAP(TST_RET_PTR, newsize);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- * Detach the shared memory segment and remove the shared memory
- * identifier associated with the shared memory.
- */
-void cleanup(void)
+static void cleanup(void)
{
+ if (shmaddr)
+ SAFE_SHMDT(shmaddr);
- /*
- * Detach the shared memory segment attached to
- * the calling process's data segment
- */
- if (shmdt(shmaddr) < 0) {
- tst_brkm(TFAIL, NULL, "shmdt() Failed to detach shared "
- "memory, error:%d", errno);
- }
-
- /*
- * Remove the shared memory identifier associated with
- * the shared memory segment and destroy the shared memory
- * segment.
- */
- if (shmctl(shmid, IPC_RMID, 0) < 0) {
- tst_brkm(TFAIL, NULL, "shmctl() Failed to remove shared "
- "memory, error:%d", errno);
- }
-
- tst_rmdir();
-
- /* Exit the program */
-
+ if (shmid != -1)
+ SAFE_SHMCTL(shmid, IPC_RMID, NULL);
}
+
+static struct tst_test test = {
+ .needs_tmpdir = 1,
+ .setup = setup,
+ .cleanup = cleanup,
+ .test_all = run,
+};
--
2.51.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [LTP] [PATCH 5/5] mremap05: Convert to new API
2026-07-21 12:41 [LTP] [PATCH 0/5] Rewrite mremap testing suite Andrea Cervesato
` (3 preceding siblings ...)
2026-07-21 12:41 ` [LTP] [PATCH 4/5] mremap04: " Andrea Cervesato
@ 2026-07-21 12:41 ` Andrea Cervesato
4 siblings, 0 replies; 7+ messages in thread
From: Andrea Cervesato @ 2026-07-21 12:41 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Convert the mremap05 test case from the legacy LTP API to the new
tst_test API.
Rewrite the test as a data-only struct tcase array with a single
run() handler, replacing the old function-pointer setup/cleanup
dispatch table. Use TST_EXP_FAIL_PTR_VOID() to verify that
mremap(MREMAP_FIXED) fails with EINVAL when MREMAP_MAYMOVE is not
set, when the target address is not page aligned, and when the old
and new ranges overlap. For the two successful-move cases, verify
both that mremap() returns the requested fixed address and that the
mapping's content is preserved across the move, including when the
target address was already mapped (proving the previous mapping
there is silently unmapped and replaced).
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mremap/mremap05.c | 315 +++++++++++-----------------
1 file changed, 127 insertions(+), 188 deletions(-)
diff --git a/testcases/kernel/syscalls/mremap/mremap05.c b/testcases/kernel/syscalls/mremap/mremap05.c
index 971cc8e5ee52c9a489782e3734178f59cd7e4a3c..3ccbda75a01ec1943ff92236767a85850e2f77df 100644
--- a/testcases/kernel/syscalls/mremap/mremap05.c
+++ b/testcases/kernel/syscalls/mremap/mremap05.c
@@ -1,239 +1,178 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2012 Linux Test Project, Inc.
- *
- * 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.
- *
- * 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.
- *
- * 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.
- *
- * 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.
+ * Copyright (c) 2026 Linux Test Project
*/
-/*
- * Test Name: mremap05
+
+/*\
+ * Verify the behavior of the ``MREMAP_FIXED`` flag of :manpage:`mremap(2)`:
*
- * Test Description:
- * Verify that MREMAP_FIXED fails without MREMAP_MAYMOVE.
- * Verify that MREMAP_FIXED|MREMAP_MAYMOVE fails if target address
- * is not page aligned.
- * Verify that MREMAP_FIXED|MREMAP_MAYMOVE fails if old range
- * overlaps with new range.
- * Verify that MREMAP_FIXED|MREMAP_MAYMOVE can move mapping to new address.
- * Verify that MREMAP_FIXED|MREMAP_MAYMOVE unmaps previous mapping
- * at the address range specified by new_address and new_size.
+ * - ``MREMAP_FIXED`` fails with ``EINVAL`` without ``MREMAP_MAYMOVE``.
+ * - ``MREMAP_FIXED | MREMAP_MAYMOVE`` fails with ``EINVAL`` if the target
+ * address is not page aligned.
+ * - ``MREMAP_FIXED | MREMAP_MAYMOVE`` fails with ``EINVAL`` if the old range
+ * overlaps with the new range.
+ * - ``MREMAP_FIXED | MREMAP_MAYMOVE`` can move a mapping to a new, free
+ * address, preserving its content.
+ * - ``MREMAP_FIXED | MREMAP_MAYMOVE`` unmaps a previously existing mapping at
+ * the target address range and replaces it with the moved mapping.
*/
#define _GNU_SOURCE
-#include "config.h"
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
-#include "test.h"
-#include "tso_safe_macros.h"
+#include "tst_test.h"
-char *TCID = "mremap05";
+static int pagesize;
-struct test_case_t {
- char *old_address;
- char *new_address;
- size_t old_size; /* in pages */
- size_t new_size; /* in pages */
+static struct tcase {
+ size_t old_pages;
+ size_t new_pages;
int flags;
- const char *msg;
- void *exp_ret;
+ int align_offset;
+ int overlap;
+ int free_dst;
+ int expect_move;
int exp_errno;
- char *ret;
- void (*setup) (struct test_case_t *);
- void (*cleanup) (struct test_case_t *);
-};
-
-static void setup(void);
-static void cleanup(void);
-static void setup0(struct test_case_t *);
-static void setup1(struct test_case_t *);
-static void setup2(struct test_case_t *);
-static void setup3(struct test_case_t *);
-static void setup4(struct test_case_t *);
-static void cleanup0(struct test_case_t *);
-static void cleanup1(struct test_case_t *);
-
-struct test_case_t tdat[] = {
+ const char *msg;
+} tcases[] = {
{
- .old_size = 1,
- .new_size = 1,
- .flags = MREMAP_FIXED,
- .msg = "MREMAP_FIXED requires MREMAP_MAYMOVE",
- .exp_ret = MAP_FAILED,
- .exp_errno = EINVAL,
- .setup = setup0,
- .cleanup = cleanup0},
+ .old_pages = 1,
+ .new_pages = 1,
+ .flags = MREMAP_FIXED,
+ .free_dst = 1,
+ .exp_errno = EINVAL,
+ .msg = "MREMAP_FIXED requires MREMAP_MAYMOVE",
+ },
{
- .old_size = 1,
- .new_size = 1,
- .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
- .msg = "new_addr has to be page aligned",
- .exp_ret = MAP_FAILED,
- .exp_errno = EINVAL,
- .setup = setup1,
- .cleanup = cleanup0},
+ .old_pages = 1,
+ .new_pages = 1,
+ .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
+ .align_offset = 1,
+ .exp_errno = EINVAL,
+ .msg = "new_addr has to be page aligned",
+ },
{
- .old_size = 2,
- .new_size = 1,
- .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
- .msg = "old/new area must not overlap",
- .exp_ret = MAP_FAILED,
- .exp_errno = EINVAL,
- .setup = setup2,
- .cleanup = cleanup0},
+ .old_pages = 2,
+ .new_pages = 1,
+ .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
+ .overlap = 1,
+ .exp_errno = EINVAL,
+ .msg = "old/new area must not overlap",
+ },
{
- .old_size = 1,
- .new_size = 1,
- .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
- .msg = "mremap #1",
- .setup = setup3,
- .cleanup = cleanup0},
+ .old_pages = 1,
+ .new_pages = 1,
+ .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
+ .free_dst = 1,
+ .expect_move = 1,
+ .msg = "move mapping to free address",
+ },
{
- .old_size = 1,
- .new_size = 1,
- .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
- .msg = "mremap #2",
- .setup = setup4,
- .cleanup = cleanup1},
+ .old_pages = 1,
+ .new_pages = 1,
+ .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
+ .free_dst = 0,
+ .expect_move = 1,
+ .msg = "move mapping onto an occupied address",
+ },
};
-static int pagesize;
-static int TST_TOTAL = sizeof(tdat) / sizeof(tdat[0]);
-
-static void free_test_area(void *p, int size)
-{
- SAFE_MUNMAP(cleanup, p, size);
-}
-
-static void *get_test_area(int size, int free_area)
+static void *get_test_area(size_t size, int free_area)
{
void *p;
- p = mmap(NULL, size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
- if (p == MAP_FAILED)
- tst_brkm(TBROK | TERRNO, cleanup, "get_test_area mmap");
+
+ p = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
if (free_area)
- free_test_area(p, size);
+ SAFE_MUNMAP(p, size);
+
return p;
}
-static void test_mremap(struct test_case_t *t)
+static void setup(void)
{
- t->ret = mremap(t->old_address, t->old_size, t->new_size, t->flags,
- t->new_address);
-
- if (t->ret == t->exp_ret) {
- if (t->ret != MAP_FAILED) {
- tst_resm(TPASS, "%s", t->msg);
- if (*(t->ret) == 0x1)
- tst_resm(TPASS, "%s value OK", t->msg);
- else
- tst_resm(TPASS, "%s value failed", t->msg);
- } else {
- if (errno == t->exp_errno)
- tst_resm(TPASS, "%s", t->msg);
- else
- tst_resm(TFAIL | TERRNO, "%s", t->msg);
- }
- } else {
- tst_resm(TFAIL, "%s ret: %p, expected: %p", t->msg,
- t->ret, t->exp_ret);
- }
+ pagesize = getpagesize();
}
-static void setup0(struct test_case_t *t)
+static void fill_pattern(char *addr, size_t pages)
{
- t->old_address = get_test_area(t->old_size * pagesize, 0);
- t->new_address = get_test_area(t->new_size * pagesize, 1);
-}
+ size_t i;
-static void setup1(struct test_case_t *t)
-{
- t->old_address = get_test_area(t->old_size * pagesize, 0);
- t->new_address = get_test_area((t->new_size + 1) * pagesize, 1) + 1;
+ for (i = 0; i < pages; i++)
+ addr[i * pagesize] = (char)(0x1 + i);
}
-static void setup2(struct test_case_t *t)
+static int check_pattern(const char *msg, char *addr, size_t pages)
{
- t->old_address = get_test_area(t->old_size * pagesize, 0);
- t->new_address = t->old_address;
-}
+ size_t i;
-static void setup3(struct test_case_t *t)
-{
- t->old_address = get_test_area(t->old_size * pagesize, 0);
- t->new_address = get_test_area(t->new_size * pagesize, 1);
- t->exp_ret = t->new_address;
- *(t->old_address) = 0x1;
-}
+ for (i = 0; i < pages; i++) {
+ char got = addr[i * pagesize];
+ char exp = (char)(0x1 + i);
-static void setup4(struct test_case_t *t)
-{
- t->old_address = get_test_area(t->old_size * pagesize, 0);
- t->new_address = get_test_area(t->new_size * pagesize, 0);
- t->exp_ret = t->new_address;
- *(t->old_address) = 0x1;
- *(t->new_address) = 0x2;
-}
+ if (got != exp) {
+ tst_res(TFAIL, "%s: page %zu content 0x%x, expected 0x%x",
+ msg, i, (unsigned char)got, (unsigned char)exp);
+ return 1;
+ }
+ }
-static void cleanup0(struct test_case_t *t)
-{
- if (t->ret == MAP_FAILED)
- free_test_area(t->old_address, t->old_size * pagesize);
- else
- free_test_area(t->ret, t->new_size * pagesize);
+ return 0;
}
-static void cleanup1(struct test_case_t *t)
+static void run(unsigned int n)
{
- if (t->ret == MAP_FAILED) {
- free_test_area(t->old_address, t->old_size * pagesize);
- free_test_area(t->new_address, t->new_size * pagesize);
+ struct tcase *tc = &tcases[n];
+ char *old_address;
+ char *new_address;
+ char *ret;
+ size_t old_size = tc->old_pages * pagesize;
+ size_t new_size = tc->new_pages * pagesize;
+
+ old_address = get_test_area(old_size, 0);
+
+ if (tc->overlap) {
+ new_address = old_address;
+ } else if (tc->align_offset) {
+ new_address = get_test_area(new_size + pagesize, 1) +
+ tc->align_offset;
} else {
- free_test_area(t->ret, t->new_size * pagesize);
+ new_address = get_test_area(new_size, tc->free_dst);
}
-}
-int main(int ac, char **av)
-{
- int lc, testno;
+ if (tc->expect_move) {
+ fill_pattern(old_address, tc->old_pages);
+
+ if (!tc->free_dst)
+ *new_address = 0x7f;
- tst_parse_opts(ac, av, NULL, NULL);
+ TESTPTR(mremap(old_address, old_size, new_size, tc->flags,
+ new_address));
+ ret = TST_RET_PTR;
- setup();
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- for (testno = 0; testno < TST_TOTAL; testno++) {
- tdat[testno].setup(&tdat[testno]);
- test_mremap(&tdat[testno]);
- tdat[testno].cleanup(&tdat[testno]);
+ if (ret != new_address) {
+ tst_res(TFAIL, "%s: ret %p, expected %p",
+ tc->msg, ret, new_address);
+ } else if (check_pattern(tc->msg, ret, tc->new_pages) == 0) {
+ tst_res(TPASS, "%s", tc->msg);
}
+ } else {
+ TST_EXP_FAIL_PTR_VOID(mremap(old_address, old_size, new_size,
+ tc->flags, new_address),
+ tc->exp_errno, "%s", tc->msg);
}
- cleanup();
- tst_exit();
-}
-static void setup(void)
-{
- pagesize = getpagesize();
+ if (TST_RET_PTR == MAP_FAILED)
+ SAFE_MUNMAP(old_address, old_size);
+ else
+ SAFE_MUNMAP(TST_RET_PTR, new_size);
}
-static void cleanup(void)
-{
-}
+static struct tst_test test = {
+ .setup = setup,
+ .test = run,
+ .tcnt = ARRAY_SIZE(tcases),
+};
--
2.51.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [LTP] mremap01: Convert to new API
2026-07-21 12:41 ` [LTP] [PATCH 1/5] mremap01: Convert to new API Andrea Cervesato
@ 2026-07-21 13:53 ` linuxtestproject.agent
0 siblings, 0 replies; 7+ messages in thread
From: linuxtestproject.agent @ 2026-07-21 13:53 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi Andrea,
On 2026-07-21, Andrea Cervesato wrote:
> mremap01: Convert to new API
> mremap02: Convert to new API
> mremap03: Convert to new API
> mremap04: Convert to new API
> mremap05: Convert to new API
Verdict - Reviewed
All five patches compile cleanly, pass `make check-mremapNN`
(checkpatch), and run to TPASS across multiple iterations. Each
conversion is traced against its original test's setup/algorithm/
oracle and preserves the full intent with no dropped scenarios, no
new leaks, and no double-unmap/double-free introduced.
The mremap04 Makefile switch from libltpipc to libltpnewipc was
verified against mremap06 and mremap07 in the same directory, neither
of which depends on the old ipc lib, so the switch does not affect
them.
---
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] 7+ messages in thread
end of thread, other threads:[~2026-07-21 13:54 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-21 12:41 [LTP] [PATCH 0/5] Rewrite mremap testing suite Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 1/5] mremap01: Convert to new API Andrea Cervesato
2026-07-21 13:53 ` [LTP] " linuxtestproject.agent
2026-07-21 12:41 ` [LTP] [PATCH 2/5] mremap02: " Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 3/5] mremap03: " Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 4/5] mremap04: " Andrea Cervesato
2026-07-21 12:41 ` [LTP] [PATCH 5/5] mremap05: " Andrea Cervesato
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox