1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) International Business Machines  Corp., 2001
4 *  07/2001 Ported by Wayne Boyer
5 * Copyright (c) 2023 SUSE LLC Avinesh Kumar <avinesh.kumar@suse.com>
6 */
7
8/*\
9 * [Description]
10 *
11 * Verify that, mmap() call with 'PROT_NONE' and a file descriptor which is
12 * open for read and write, succeeds to map the file creating mapped memory,
13 * but any attempt to access the contents of the mapped region causes the
14 * SIGSEGV signal.
15 */
16
17#include <stdlib.h>
18#include <setjmp.h>
19#include "tst_test.h"
20
21#define TEMPFILE "mmapfile"
22static size_t page_sz;
23static volatile char *addr;
24static int fd;
25static volatile int sig_flag;
26static sigjmp_buf env;
27
28static void sig_handler(int sig)
29{
30	if (sig == SIGSEGV) {
31		sig_flag = 1;
32		siglongjmp(env, 1);
33	}
34}
35
36static void setup(void)
37{
38	char *buf;
39
40	SAFE_SIGNAL(SIGSEGV, sig_handler);
41
42	page_sz = getpagesize();
43	buf = SAFE_MALLOC(page_sz);
44	memset(buf, 'A', page_sz);
45
46	fd = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);
47	SAFE_WRITE(SAFE_WRITE_ALL, fd, buf, page_sz);
48	free(buf);
49}
50
51static void run(void)
52{
53	addr = mmap(NULL, page_sz, PROT_NONE, MAP_FILE | MAP_SHARED, fd, 0);
54	if (addr == MAP_FAILED) {
55		tst_res(TFAIL | TERRNO, "mmap() of %s failed", TEMPFILE);
56		return;
57	}
58
59	if (sigsetjmp(env, 1) == 0)
60		tst_res(TINFO, "Trying to access mapped region: %c", addr[0]);
61
62	if (sig_flag)
63		tst_res(TPASS, "Received SIGSEGV signal as expected");
64	else
65		tst_res(TFAIL, "SIGSEGV signal not received");
66
67	SAFE_MUNMAP((char *)addr, page_sz);
68
69	sig_flag = 0;
70}
71
72static void cleanup(void)
73{
74	if (fd > 0)
75		SAFE_CLOSE(fd);
76}
77
78static struct tst_test test = {
79	.setup = setup,
80	.cleanup = cleanup,
81	.test_all = run,
82	.needs_tmpdir = 1
83};
84