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