* [LTP] [PATCH v3 1/7] mremap01: Convert to new API
2026-08-07 12:17 [LTP] [PATCH v3 0/7] Rewrite mremap testing suite Andrea Cervesato
@ 2026-08-07 12:17 ` Andrea Cervesato
2026-08-07 13:05 ` [LTP] " linuxtestproject.agent
2026-08-07 12:17 ` [LTP] [PATCH v3 2/7] mremap02: " Andrea Cervesato
` (5 subsequent siblings)
6 siblings, 1 reply; 11+ messages in thread
From: Andrea Cervesato @ 2026-08-07 12:17 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.
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
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 8c241d45c..c6f2cb6a9 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_FTRUNCATE(fildes, 0);
+ 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);
}
-/*
- * 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] 11+ messages in thread* Re: [LTP] mremap01: Convert to new API
2026-08-07 12:17 ` [LTP] [PATCH v3 1/7] mremap01: Convert to new API Andrea Cervesato
@ 2026-08-07 13:05 ` linuxtestproject.agent
0 siblings, 0 replies; 11+ messages in thread
From: linuxtestproject.agent @ 2026-08-07 13:05 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi Andrea,
On Fri, 7 Aug 2026, Andrea Cervesato wrote:
> mremap01: Convert to new API
--- [PATCH 1/7] ---
> static int verify_file(void)
> {
> [...]
> tst_res(TFAIL, "file[%zu] == 0x%02x, expected 0x%02x",
> off, (unsigned char)got, (unsigned char)off);
> return 1;
> [...]
> if (verify_file())
> tst_res(TFAIL, "mremap()'d region did not sync to the file");
Could verify_file() report the final result directly instead of returning
pass/fail status to run()? A mismatch currently produces both the precise
byte failure and a second generic TFAIL for the same check.
--- [PATCH 3/7] ---
> * - Obtain an unmapped address via ``tst_get_bad_addr()``.
> [...]
> bad_addr = tst_get_bad_addr(NULL);
Could this use an address that is actually unmapped, or describe the
partial-VMA case that is really tested? tst_get_bad_addr() creates and
retains a one-page PROT_NONE mapping, so old_address itself is mapped.
On Linux 7.2 this returns EFAULT because memsize extends beyond that
one-page VMA, not because old_address points to an unmapped region. The
description, algorithm, and commit message therefore claim different
coverage from the executed path.
--- [PATCH 4/7] ---
> 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
> [...]
> Switch the Makefile from libltpipc to libltpnewipc
Could the commit message be updated to match the patch? The code replaces
SysV shared memory with a private anonymous mapping and removes the IPC
library dependency; it does not use libltpnewipc or GETIPCKEY().
--- [PATCH 5/7] ---
> Convert the mremap05 test case from the legacy LTP API to the new
> tst_test API.
Could the body explain why this semantic rewrite is needed and mention
that the positive MREMAP_FIXED cases are split into the later dedicated
test? It currently only restates the subject and does not give the
motivation or explain the series dependency.
--- [PATCH 6/7] ---
> static int check_pattern(char *addr, size_t pages)
> {
> [...]
> if (got != exp)
> return 1;
> [...]
> else if (check_pattern(ret, tc->new_pages))
> tst_res(TFAIL, "%s: pattern mismatch", tc->msg);
Could check_pattern() report the result where the mismatch is detected
instead of propagating pass/fail through its return value? Reporting the
offset and observed value there would also make the failure actionable
rather than producing only "pattern mismatch".
Verdict - Needs revision
---
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] 11+ messages in thread
* [LTP] [PATCH v3 2/7] mremap02: Convert to new API
2026-08-07 12:17 [LTP] [PATCH v3 0/7] Rewrite mremap testing suite Andrea Cervesato
2026-08-07 12:17 ` [LTP] [PATCH v3 1/7] mremap01: Convert to new API Andrea Cervesato
@ 2026-08-07 12:17 ` Andrea Cervesato
2026-08-07 12:17 ` [LTP] [PATCH v3 3/7] mremap03: " Andrea Cervesato
` (4 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2026-08-07 12:17 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.
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mremap/mremap02.c | 201 ++++++----------------------
1 file changed, 44 insertions(+), 157 deletions(-)
diff --git a/testcases/kernel/syscalls/mremap/mremap02.c b/testcases/kernel/syscalls/mremap/mremap02.c
index 2dabc6847..354a67c89 100644
--- a/testcases/kernel/syscalls/mremap/mremap02.c
+++ b/testcases/kernel/syscalls/mremap/mremap02.c
@@ -1,178 +1,65 @@
+// 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.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
+/*\
+ * 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.
*
- * 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.
+ * [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.
+ * - 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"
-
-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 */
+static long page_size;
+static size_t new_size;
+static void *page;
+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++) {
+ page_size = getpagesize();
+ new_size = page_size * 2;
- 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_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");
+ TST_EXP_FAIL_PTR_VOID(mremap(bad_addr, page_size, new_size,
+ MREMAP_MAYMOVE), EINVAL);
+
+ if (TST_RET_PTR != MAP_FAILED) {
+ SAFE_MUNMAP(TST_RET_PTR, new_size);
+ page = SAFE_MMAP(NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ bad_addr = (char *)page + 1;
}
-
- /* Get the New size of virtual memory block after resize */
- newsize = (memsize * 2);
-
- /* Set the old virtual memory address */
- addr = (char *)(addr + (memsize - 1));
}
-/*
- * 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] 11+ messages in thread* [LTP] [PATCH v3 3/7] mremap03: Convert to new API
2026-08-07 12:17 [LTP] [PATCH v3 0/7] Rewrite mremap testing suite Andrea Cervesato
2026-08-07 12:17 ` [LTP] [PATCH v3 1/7] mremap01: Convert to new API Andrea Cervesato
2026-08-07 12:17 ` [LTP] [PATCH v3 2/7] mremap02: " Andrea Cervesato
@ 2026-08-07 12:17 ` Andrea Cervesato
2026-08-07 12:17 ` [LTP] [PATCH v3 4/7] mremap04: " Andrea Cervesato
` (3 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2026-08-07 12:17 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().
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
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 02b79bc47..6003657d4 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] 11+ messages in thread* [LTP] [PATCH v3 4/7] mremap04: Convert to new API
2026-08-07 12:17 [LTP] [PATCH v3 0/7] Rewrite mremap testing suite Andrea Cervesato
` (2 preceding siblings ...)
2026-08-07 12:17 ` [LTP] [PATCH v3 3/7] mremap03: " Andrea Cervesato
@ 2026-08-07 12:17 ` Andrea Cervesato
2026-08-07 12:17 ` [LTP] [PATCH v3 5/7] mremap05: " Andrea Cervesato
` (2 subsequent siblings)
6 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2026-08-07 12:17 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.
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mremap/Makefile | 3 -
testcases/kernel/syscalls/mremap/mremap04.c | 265 +++++-----------------------
2 files changed, 43 insertions(+), 225 deletions(-)
diff --git a/testcases/kernel/syscalls/mremap/Makefile b/testcases/kernel/syscalls/mremap/Makefile
index 8811b887e..e774bac01 100644
--- a/testcases/kernel/syscalls/mremap/Makefile
+++ b/testcases/kernel/syscalls/mremap/Makefile
@@ -3,11 +3,8 @@
top_srcdir ?= ../../../..
-LTPLIBS = ipc
-
include $(top_srcdir)/include/mk/testcases.mk
-mremap04: LTPLDLIBS = -lltpipc
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 53902df73..e9e394188 100644
--- a/testcases/kernel/syscalls/mremap/mremap04.c
+++ b/testcases/kernel/syscalls/mremap/mremap04.c
@@ -1,245 +1,66 @@
+// 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.
+/*\
+ * 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.
*
- * 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)
- * 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...
- *
- * 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.
- *
- * RESTRICTIONS:
- * None.
+ * - map an anonymous region of two pages
+ * - call mremap() on the mapped 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 "test.h"
+static void *addr = MAP_FAILED;
+static size_t memsize;
+static size_t newsize;
-#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 */
-
-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);
- }
- }
-
- cleanup();
- tst_exit();
+ memsize = getpagesize();
+ newsize = memsize * 2;
+ addr = SAFE_MMAP(NULL, newsize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 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. The next page
+ * is occupied by our own mapping, so it cannot be expanded in place.
*/
- 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(addr, 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);
+ addr = SAFE_MMAP(NULL, newsize, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
}
-/*
- * 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)
{
-
- /*
- * 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 (addr != MAP_FAILED)
+ SAFE_MUNMAP(addr, newsize);
}
+
+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] 11+ messages in thread* [LTP] [PATCH v3 5/7] mremap05: Convert to new API
2026-08-07 12:17 [LTP] [PATCH v3 0/7] Rewrite mremap testing suite Andrea Cervesato
` (3 preceding siblings ...)
2026-08-07 12:17 ` [LTP] [PATCH v3 4/7] mremap04: " Andrea Cervesato
@ 2026-08-07 12:17 ` Andrea Cervesato
2026-08-07 12:17 ` [LTP] [PATCH v3 6/7] mremap08: Extract test from mremap05 Andrea Cervesato
2026-08-07 12:17 ` [LTP] [PATCH v3 7/7] mremap09: Add test for expanding over unmapped gap Andrea Cervesato
6 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2026-08-07 12:17 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.
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mremap/mremap05.c | 278 ++++++++--------------------
1 file changed, 75 insertions(+), 203 deletions(-)
diff --git a/testcases/kernel/syscalls/mremap/mremap05.c b/testcases/kernel/syscalls/mremap/mremap05.c
index 971cc8e5e..4e906a044 100644
--- a/testcases/kernel/syscalls/mremap/mremap05.c
+++ b/testcases/kernel/syscalls/mremap/mremap05.c
@@ -1,239 +1,111 @@
+// 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)`
+ * when invalid arguments are provided:
*
- * 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.
*/
#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 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[] = {
- {
- .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_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},
+ const char *msg;
+} tcases[] = {
{
- .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 = 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 = "mremap #1",
- .setup = setup3,
- .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 = 1,
- .new_size = 1,
- .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
- .msg = "mremap #2",
- .setup = setup4,
- .cleanup = cleanup1},
+ .old_pages = 2,
+ .new_pages = 1,
+ .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
+ .overlap = 1,
+ .exp_errno = EINVAL,
+ .msg = "old/new area must not overlap",
+ },
};
-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");
- if (free_area)
- free_test_area(p, size);
- return p;
-}
-static void test_mremap(struct test_case_t *t)
-{
- t->ret = mremap(t->old_address, t->old_size, t->new_size, t->flags,
- t->new_address);
+ p = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- 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);
- }
-}
-
-static void setup0(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);
-}
-
-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;
-}
+ if (free_area)
+ SAFE_MUNMAP(p, size);
-static void setup2(struct test_case_t *t)
-{
- t->old_address = get_test_area(t->old_size * pagesize, 0);
- t->new_address = t->old_address;
+ return p;
}
-static void setup3(struct test_case_t *t)
+static void setup(void)
{
- 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;
+ pagesize = getpagesize();
}
-static void setup4(struct test_case_t *t)
+static void run(unsigned int n)
{
- 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;
-}
+ struct tcase *tc = &tcases[n];
+ char *old_address;
+ char *new_address;
+ size_t old_size = tc->old_pages * pagesize;
+ size_t new_size = tc->new_pages * pagesize;
-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);
-}
+ old_address = get_test_area(old_size, 0);
-static void cleanup1(struct test_case_t *t)
-{
- 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);
+ 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;
- tst_parse_opts(ac, av, NULL, NULL);
-
- 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]);
- }
- }
- cleanup();
- tst_exit();
-}
+ TST_EXP_FAIL_PTR_VOID(mremap(old_address, old_size, new_size,
+ tc->flags, new_address),
+ tc->exp_errno, "%s", tc->msg);
-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] 11+ messages in thread* [LTP] [PATCH v3 6/7] mremap08: Extract test from mremap05
2026-08-07 12:17 [LTP] [PATCH v3 0/7] Rewrite mremap testing suite Andrea Cervesato
` (4 preceding siblings ...)
2026-08-07 12:17 ` [LTP] [PATCH v3 5/7] mremap05: " Andrea Cervesato
@ 2026-08-07 12:17 ` Andrea Cervesato
2026-08-07 12:17 ` [LTP] [PATCH v3 7/7] mremap09: Add test for expanding over unmapped gap Andrea Cervesato
6 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2026-08-07 12:17 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Extract a new test from mremap05 that verifies the behavior of the
MREMAP_FIXED flag when:
- 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.
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/mremap/.gitignore | 1 +
testcases/kernel/syscalls/mremap/mremap08.c | 127 ++++++++++++++++++++++++++++
3 files changed, 129 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index b024d4c43..ede795a48 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -946,6 +946,7 @@ mremap04 mremap04
mremap05 mremap05
mremap06 mremap06
mremap07 mremap07
+mremap08 mremap08
mseal01 mseal01
mseal02 mseal02
diff --git a/testcases/kernel/syscalls/mremap/.gitignore b/testcases/kernel/syscalls/mremap/.gitignore
index 292899e03..dd4bf4e8e 100644
--- a/testcases/kernel/syscalls/mremap/.gitignore
+++ b/testcases/kernel/syscalls/mremap/.gitignore
@@ -5,3 +5,4 @@
/mremap05
/mremap06
/mremap07
+/mremap08
diff --git a/testcases/kernel/syscalls/mremap/mremap08.c b/testcases/kernel/syscalls/mremap/mremap08.c
new file mode 100644
index 000000000..a2c589447
--- /dev/null
+++ b/testcases/kernel/syscalls/mremap/mremap08.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Linux Test Project
+ */
+
+/*\
+ * Verify the behavior of the ``MREMAP_FIXED`` flag of :manpage:`mremap(2)`:
+ *
+ * - ``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 <sys/mman.h>
+#include "tst_test.h"
+
+static int pagesize;
+
+static struct tcase {
+ size_t old_pages;
+ size_t new_pages;
+ int flags;
+ int free_dst;
+ const char *msg;
+} tcases[] = {
+ {
+ .old_pages = 1,
+ .new_pages = 1,
+ .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
+ .free_dst = 1,
+ .msg = "move mapping to free address",
+ },
+ {
+ .old_pages = 1,
+ .new_pages = 1,
+ .flags = MREMAP_FIXED | MREMAP_MAYMOVE,
+ .free_dst = 0,
+ .msg = "move mapping onto an occupied address",
+ },
+};
+
+static void *get_test_area(size_t size, int free_area)
+{
+ void *p;
+
+ p = SAFE_MMAP(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ if (free_area)
+ SAFE_MUNMAP(p, size);
+
+ return p;
+}
+
+static void setup(void)
+{
+ pagesize = getpagesize();
+}
+
+static void fill_pattern(char *addr, size_t pages, char *new_addr, int free_dst)
+{
+ size_t i;
+
+ for (i = 0; i < pages; i++)
+ addr[i * pagesize] = (char)(0x1 + i);
+
+ if (!free_dst)
+ *new_addr = 0x7f;
+}
+
+static int check_pattern(char *addr, size_t pages)
+{
+ size_t i;
+
+ for (i = 0; i < pages; i++) {
+ char got = addr[i * pagesize];
+ char exp = (char)(0x1 + i);
+
+ if (got != exp)
+ return 1;
+ }
+
+ return 0;
+}
+
+static void run(unsigned int n)
+{
+ 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);
+ new_address = get_test_area(new_size, tc->free_dst);
+
+ fill_pattern(old_address, tc->old_pages, new_address, tc->free_dst);
+
+ TESTPTR(mremap(old_address, old_size, new_size, tc->flags, new_address));
+ ret = TST_RET_PTR;
+
+ if (ret == MAP_FAILED) {
+ tst_res(TFAIL | TTERRNO, "%s failed", tc->msg);
+ SAFE_MUNMAP(old_address, old_size);
+ if (!tc->free_dst)
+ SAFE_MUNMAP(new_address, new_size);
+ return;
+ }
+
+ if (ret != new_address)
+ tst_res(TFAIL, "%s: ret %p, expected %p", tc->msg, ret, new_address);
+ else if (check_pattern(ret, tc->new_pages))
+ tst_res(TFAIL, "%s: pattern mismatch", tc->msg);
+ else
+ tst_res(TPASS, "%s", tc->msg);
+
+ SAFE_MUNMAP(ret, new_size);
+}
+
+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] 11+ messages in thread* [LTP] [PATCH v3 7/7] mremap09: Add test for expanding over unmapped gap
2026-08-07 12:17 [LTP] [PATCH v3 0/7] Rewrite mremap testing suite Andrea Cervesato
` (5 preceding siblings ...)
2026-08-07 12:17 ` [LTP] [PATCH v3 6/7] mremap08: Extract test from mremap05 Andrea Cervesato
@ 2026-08-07 12:17 ` Andrea Cervesato
6 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2026-08-07 12:17 UTC (permalink / raw)
To: Linux Test Project
From: Andrea Cervesato <andrea.cervesato@suse.com>
Add a test case for mremap() without MREMAP_MAYMOVE where we map
three pages, unmap the middle one to create a hole, and then
attempt to expand the first page to cover all three. The mremap()
call must fail with ENOMEM since the third page is occupied.
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/syscalls | 1 +
testcases/kernel/syscalls/mremap/.gitignore | 1 +
testcases/kernel/syscalls/mremap/mremap09.c | 59 +++++++++++++++++++++++++++++
3 files changed, 61 insertions(+)
diff --git a/runtest/syscalls b/runtest/syscalls
index ede795a48..5166886c4 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -947,6 +947,7 @@ mremap05 mremap05
mremap06 mremap06
mremap07 mremap07
mremap08 mremap08
+mremap09 mremap09
mseal01 mseal01
mseal02 mseal02
diff --git a/testcases/kernel/syscalls/mremap/.gitignore b/testcases/kernel/syscalls/mremap/.gitignore
index dd4bf4e8e..a7ae3b643 100644
--- a/testcases/kernel/syscalls/mremap/.gitignore
+++ b/testcases/kernel/syscalls/mremap/.gitignore
@@ -6,3 +6,4 @@
/mremap06
/mremap07
/mremap08
+/mremap09
diff --git a/testcases/kernel/syscalls/mremap/mremap09.c b/testcases/kernel/syscalls/mremap/mremap09.c
new file mode 100644
index 000000000..28ab9e310
--- /dev/null
+++ b/testcases/kernel/syscalls/mremap/mremap09.c
@@ -0,0 +1,59 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2026 Linux Test Project
+ */
+
+/*\
+ * 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.
+ *
+ * [Algorithm]
+ *
+ * - map an anonymous region of three pages
+ * - unmap the middle page to create a gap
+ * - call mremap() on the first page to grow it to three pages with ``flags``
+ * set to 0
+ * - expect the call to fail with ``MAP_FAILED`` and ``ENOMEM`` since the
+ * third page is occupied.
+ */
+
+#define _GNU_SOURCE
+#include <sys/mman.h>
+#include "tst_test.h"
+
+static size_t pagesize;
+static void *addr = MAP_FAILED;
+
+static void setup(void)
+{
+ pagesize = getpagesize();
+}
+
+static void run(void)
+{
+ size_t map_size = 3 * pagesize;
+ size_t old_size = 1 * pagesize;
+ size_t new_size = 3 * pagesize;
+
+ addr = SAFE_MMAP(NULL, map_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+
+ /* unmap the middle page to create a gap */
+ SAFE_MUNMAP((char *)addr + pagesize, pagesize);
+
+ TST_EXP_FAIL_PTR_VOID(mremap(addr, old_size, new_size, 0), ENOMEM);
+
+ if (TST_RET_PTR != MAP_FAILED) {
+ SAFE_MUNMAP(TST_RET_PTR, new_size);
+ return;
+ }
+
+ SAFE_MUNMAP(addr, pagesize);
+ SAFE_MUNMAP((char *)addr + 2 * pagesize, pagesize);
+}
+
+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] 11+ messages in thread