[LTP] [PATCH 3/3] syscalls: munmap03: Convert to new API
Ricardo B. Marlière
rbm@suse.com
Fri Jul 4 17:23:13 CEST 2025
On Fri Jul 4, 2025 at 9:14 AM -03, Andrea Cervesato wrote:
> Hi!
>
> On 7/3/25 8:39 PM, Ricardo B. Marlière via ltp wrote:
>> From: Ricardo B. Marlière <rbm@suse.com>
>>
>> Signed-off-by: Ricardo B. Marlière <rbm@suse.com>
>> ---
>> testcases/kernel/syscalls/munmap/munmap03.c | 162 ++++++++--------------------
>> 1 file changed, 43 insertions(+), 119 deletions(-)
>>
>> diff --git a/testcases/kernel/syscalls/munmap/munmap03.c b/testcases/kernel/syscalls/munmap/munmap03.c
>> index 60bcb93b0e359b579294d6745e1e729340c0d92e..7aab587ad4ca0e0add973a7344a338240f485647 100644
>> --- a/testcases/kernel/syscalls/munmap/munmap03.c
>> +++ b/testcases/kernel/syscalls/munmap/munmap03.c
>> @@ -1,148 +1,72 @@
>> +// 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) 2025 SUSE LLC Ricardo B. Marlière <rbm@suse.com>
>> */
>>
>> -/*
>> - * Test Description:
>> - * Verify that,
>> - * 1. munmap() fails with -1 return value and sets errno to EINVAL
>> - * if addresses in the range [addr,addr+len) are outside the valid
>> - * range for the address space of a process.
>> - * 2. munmap() fails with -1 return value and sets errno to EINVAL
>> - * if the len argument is 0.
>> - * 3. munmap() fails with -1 return value and sets errno to EINVAL
>> - * if the addr argument is not a multiple of the page size as
>> - * returned by sysconf().
>> +/*\
>> + * Verify that, munmap() fails with errno:
>> *
>> - * HISTORY
>> - * 07/2001 Ported by Wayne Boyer
>> + * - EINVAL, if addresses in the range [addr,addr+len) are outside the valid
>> + * range for the address space of a process.
>> + * - EINVAL, if the len argument is 0.
>> + * - EINVAL, if the addr argument is not a multiple of the page size as
>> + * returned by sysconf().
>> */
>>
>> -#include <errno.h>
>> -#include <unistd.h>
>> -#include <fcntl.h>
>> -#include <sys/mman.h>
>> -#include <sys/resource.h>
>> -#include <sys/stat.h>
>> -
>> -#include "test.h"
>> -#include "safe_macros.h"
>> -
>> -char *TCID = "munmap03";
>> +#include "tst_test.h"
>>
>> static size_t page_sz;
>> static char *global_addr;
>> static size_t global_maplen;
>>
>> -static void setup(void);
>> -static void cleanup(void);
>> +static struct tcase {
>> + int exp_errno;
>> + char *addr;
>> + int len;
>>
>> -static void test_einval1(void);
>> -static void test_einval2(void);
>> -static void test_einval3(void);
>> -static void (*testfunc[])(void) = { test_einval1, test_einval2, test_einval3 };
>> -int TST_TOTAL = ARRAY_SIZE(testfunc);
>> +} tcases[] = {
>> + { EINVAL, NULL, 0 },
>> + { EINVAL, NULL, 0 },
>> + { EINVAL, NULL, 0 },
>> +};
>>
>> -int main(int ac, char **av)
>> +static void run(unsigned int i)
>> {
>> - int i, lc;
>> + struct tcase *tc = &tcases[i];
>>
>> - tst_parse_opts(ac, av, NULL, NULL);
>> -
>> - setup();
>> -
>> - for (lc = 0; TEST_LOOPING(lc); lc++) {
>> - tst_count = 0;
>> -
>> - for (i = 0; i < TST_TOTAL; i++)
>> - (*testfunc[i])();
>> - }
>> -
>> - cleanup();
>> - tst_exit();
>> + TST_EXP_FAIL(munmap(tc->addr, tc->len), EINVAL);
>> }
>>
>> static void setup(void)
>> -{
>> - tst_sig(NOFORK, DEF_HANDLER, cleanup);
>> -
>> - TEST_PAUSE;
>> -
>> - page_sz = (size_t)sysconf(_SC_PAGESIZE);
>> -
>> - global_maplen = page_sz * 2;
>> - global_addr = SAFE_MMAP(cleanup, NULL, global_maplen, PROT_READ |
>> - PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
>> -}
>> -
>> -static void check_and_print(int expected_errno)
>> -{
>> - if (TEST_RETURN == -1) {
>> - if (TEST_ERRNO == expected_errno) {
>> - tst_resm(TPASS | TTERRNO, "failed as expected");
>> - } else {
>> - tst_resm(TFAIL | TTERRNO,
>> - "failed unexpectedly; expected - %d : %s",
>> - expected_errno, strerror(expected_errno));
>> - }
>> - } else {
>> - tst_resm(TFAIL, "munmap succeeded unexpectedly");
>> - }
>> -}
>> -
>> -static void test_einval1(void)
>> {
>> struct rlimit brkval;
>> - char *addr;
>> - size_t map_len;
>> -
>> - SAFE_GETRLIMIT(cleanup, RLIMIT_DATA, &brkval);
>> -
>> - addr = (char *)brkval.rlim_max;
>> - map_len = page_sz * 2;
>> -
>> - TEST(munmap(addr, map_len));
>>
>> - check_and_print(EINVAL);
>> -}
>> -
>> -static void test_einval2(void)
>> -{
>> - char *addr = global_addr;
>> - size_t map_len = 0;
>> -
>> - TEST(munmap(addr, map_len));
>> -
>> - check_and_print(EINVAL);
>> -}
>> + page_sz = getpagesize();
>> + global_maplen = page_sz * 2;
>> + global_addr = SAFE_MMAP(NULL, global_maplen, PROT_READ | PROT_WRITE,
>> + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
>>
>> -static void test_einval3(void)
>> -{
>> - char *addr = (char *)(global_addr + 1);
>> - size_t map_len = page_sz;
>> + SAFE_GETRLIMIT(RLIMIT_DATA, &brkval);
>> + tcases[0].addr = (char *)brkval.rlim_max;
>> + tcases[0].len = page_sz * 2;
>>
>> - TEST(munmap(addr, map_len));
>> + tcases[1].addr = global_addr;
>> + tcases[1].len = 0;
>>
>> - check_and_print(EINVAL);
>> + tcases[2].addr = (char *)(global_addr + 1);
>> + tcases[2].len = page_sz;
> We don't usually use this approach because it's error prone. Instead, we
> create different static variables and we reference them to the structure
> after setting them inside setup(). For an example, you can take a look
> at lsm_set_self_attr01.c .
Ack.
>> }
>>
>> static void cleanup(void)
>> {
>> - if (munmap(global_addr, global_maplen) == -1)
>> - tst_resm(TWARN | TERRNO, "munmap failed");
>> + SAFE_MUNMAP(global_addr, global_maplen);
>> }
>> +
>> +static struct tst_test test = {
>> + .test = run,
>> + .tcnt = ARRAY_SIZE(tcases),
>> + .setup = setup,
>> + .cleanup = cleanup,
>> +};
>>
> We are still missing many other errors which could be tested. Please
> take a look at "man munmap" ERRORS section and try to verify how many of
> them could be actually be tested in this code by passing invalid data.
Most of those are for mmap. The only one left seems to be ENOMEM, which
I don't think it's viable to test. WDYT?
>
> - Andrea
More information about the ltp
mailing list