xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/mmap/mmap13.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2013 FNST, DAN LI <[email protected]>
4  * Copyright (c) 2024 SUSE LLC Avinesh Kumar <[email protected]>
5  */
6 
7 /*\
8  * [Description]
9  *
10  * Verify that, mmap() call succeeds to create a file mapping with length
11  * argument greater than the file size but any attempt to reference the
12  * memory region which does not correspond to the file causes SIGBUS signal.
13  */
14 
15 #include <stdlib.h>
16 #include <setjmp.h>
17 #include "tst_test.h"
18 
19 #define TEMPFILE	"mmapfile"
20 static size_t page_sz;
21 static char *addr;
22 static int fd;
23 static volatile sig_atomic_t pass;
24 static sigjmp_buf env;
25 
sig_handler(int sig)26 static void sig_handler(int sig)
27 {
28 	if (sig == SIGBUS) {
29 		pass = 1;
30 		siglongjmp(env, 1);
31 	}
32 }
33 
setup(void)34 static void setup(void)
35 {
36 	SAFE_SIGNAL(SIGBUS, sig_handler);
37 
38 	page_sz = getpagesize();
39 
40 	fd = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);
41 	SAFE_FTRUNCATE(fd, page_sz / 2);
42 }
43 
run(void)44 static void run(void)
45 {
46 	char *ch;
47 
48 	addr = mmap(0, page_sz * 2, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0);
49 	if (addr == MAP_FAILED) {
50 		tst_res(TFAIL | TERRNO, "mmap() of %s failed", TEMPFILE);
51 		return;
52 	}
53 
54 	if (sigsetjmp(env, 1) == 0) {
55 		ch = addr + page_sz + 1;
56 		*ch = 0;
57 	}
58 
59 	if (pass == 1)
60 		tst_res(TPASS, "Received SIGBUS signal as expected");
61 	else
62 		tst_res(TFAIL, "SIGBUS signal not received");
63 
64 	SAFE_MUNMAP(addr, page_sz * 2);
65 }
66 
cleanup(void)67 static void cleanup(void)
68 {
69 	if (fd > 0)
70 		SAFE_CLOSE(fd);
71 }
72 
73 static struct tst_test test = {
74 	.setup = setup,
75 	.cleanup = cleanup,
76 	.test_all = run,
77 	.needs_tmpdir = 1
78 };
79