Skip to content

Commit

Permalink
Add madvise12 test
Browse files Browse the repository at this point in the history
Verify that MADV_GUARD_INSTALL is causing SIGSEGV when someone is
trying to access memory advised with it.

Closes: #1210
Reviewed-by: Petr Vorel <[email protected]>
Signed-off-by: Andrea Cervesato <[email protected]>
  • Loading branch information
acerv committed Dec 11, 2024
1 parent 048b168 commit 34dc7d2
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 0 deletions.
1 change: 1 addition & 0 deletions runtest/syscalls
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,7 @@ madvise08 madvise08
madvise09 madvise09
madvise10 madvise10
madvise11 madvise11
madvise12 madvise12

newuname01 newuname01

Expand Down
1 change: 1 addition & 0 deletions testcases/kernel/syscalls/madvise/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
/madvise09
/madvise10
/madvise11
/madvise12
105 changes: 105 additions & 0 deletions testcases/kernel/syscalls/madvise/madvise12.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2024 Andrea Cervesato <[email protected]>
*/

/*\
* [Description]
*
* Verify that MADV_GUARD_INSTALL is causing SIGSEGV when someone is accessing
* memory advised with it.
*
* This is a test for feature implemented in
* 662df3e5c376 ("mm: madvise: implement lightweight guard page mechanism")
*
* [Algorithm]
*
* - allocate a certain amount of memory
* - advise memory with MADV_GUARD_INSTALL
* - access to memory from within a child and verify it gets killed by SIGSEGV
* - release memory with MADV_GUARD_REMOVE
* - verify that memory has not been modified before child got killed
* - modify memory within a new child
* - verify that memory is accessable and child was not killed by SIGSEGV
*/

#include "tst_test.h"
#include "lapi/mmap.h"

#define MAP_SIZE (8 * TST_KB)

static char *addr;

static void run(void)
{
pid_t pid;
int status;

memset(addr, 0, MAP_SIZE);

TST_EXP_PASS(madvise(addr, MAP_SIZE, MADV_GUARD_INSTALL));

pid = SAFE_FORK();
if (!pid) {
tst_res(TINFO, "Modifying memory content");

memset(addr, 'a', MAP_SIZE);
exit(0);
}

SAFE_WAITPID(pid, &status, 0);

if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV)
tst_res(TPASS, "Child ended by SIGSEGV as expected");
else
tst_res(TFAIL, "Child: %s", tst_strstatus(status));

TST_EXP_PASS(madvise(addr, MAP_SIZE, MADV_GUARD_REMOVE));

for (int i = 0; i < MAP_SIZE; i++) {
if (addr[i] == 'a') {
tst_res(TFAIL, "Memory content has been modified");
return;
}
}

tst_res(TPASS, "Memory content didn't change");

pid = SAFE_FORK();
if (!pid) {
tst_res(TINFO, "Modifying memory content");

memset(addr, 'b', MAP_SIZE);
exit(0);
}

SAFE_WAITPID(pid, &status, 0);

if (!WIFSIGNALED(status))
tst_res(TPASS, "Child ended without being signaled");
else
tst_res(TFAIL, "Child ended with %s", tst_strstatus(status));
}

static void setup(void)
{
addr = SAFE_MMAP(NULL, MAP_SIZE,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
}

static void cleanup(void)
{
if (addr)
SAFE_MUNMAP(addr, MAP_SIZE);
}

static struct tst_test test = {
.test_all = run,
.setup = setup,
.cleanup = cleanup,
.needs_root = 1,
.forks_child = 1,
.min_kver = "6.13",
};

0 comments on commit 34dc7d2

Please sign in to comment.