Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/vm/page_fault_signal.c
39534 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2019 Jilles Tjoelker
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* 2. Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
*
15
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*/
27
28
#include <sys/mman.h>
29
30
#include <atf-c.h>
31
#include <fcntl.h>
32
#include <setjmp.h>
33
#include <signal.h>
34
#include <stdio.h>
35
36
static sigjmp_buf sig_env;
37
static volatile int last_sig, last_code;
38
39
static void
40
sighandler(int sig, siginfo_t *info, void *context __unused)
41
{
42
43
last_sig = sig;
44
last_code = info->si_code;
45
siglongjmp(sig_env, 1);
46
}
47
48
static void
49
setup_signals(void)
50
{
51
struct sigaction sa;
52
int r;
53
54
sa.sa_sigaction = sighandler;
55
sa.sa_flags = SA_RESTART | SA_RESETHAND | SA_SIGINFO;
56
r = sigfillset(&sa.sa_mask);
57
ATF_REQUIRE(r != -1);
58
r = sigaction(SIGILL, &sa, NULL);
59
ATF_REQUIRE(r != -1);
60
r = sigaction(SIGBUS, &sa, NULL);
61
ATF_REQUIRE(r != -1);
62
r = sigaction(SIGSEGV, &sa, NULL);
63
ATF_REQUIRE(r != -1);
64
}
65
66
ATF_TC_WITHOUT_HEAD(page_fault_signal__segv_maperr_1);
67
ATF_TC_BODY(page_fault_signal__segv_maperr_1, tc)
68
{
69
int *p;
70
int r;
71
int sz;
72
73
sz = getpagesize();
74
p = mmap(NULL, sz, PROT_READ, MAP_ANON, -1, 0);
75
ATF_REQUIRE(p != MAP_FAILED);
76
r = munmap(p, sz);
77
ATF_REQUIRE(r != -1);
78
if (sigsetjmp(sig_env, 1) == 0) {
79
setup_signals();
80
*(volatile int *)p = 1;
81
}
82
ATF_CHECK_EQ(SIGSEGV, last_sig);
83
ATF_CHECK_EQ(SEGV_MAPERR, last_code);
84
}
85
86
ATF_TC_WITHOUT_HEAD(page_fault_signal__segv_accerr_1);
87
ATF_TC_BODY(page_fault_signal__segv_accerr_1, tc)
88
{
89
int *p;
90
int sz;
91
92
sz = getpagesize();
93
p = mmap(NULL, sz, PROT_READ, MAP_ANON, -1, 0);
94
ATF_REQUIRE(p != MAP_FAILED);
95
if (sigsetjmp(sig_env, 1) == 0) {
96
setup_signals();
97
*(volatile int *)p = 1;
98
}
99
(void)munmap(p, sz);
100
ATF_CHECK_EQ(SIGSEGV, last_sig);
101
ATF_CHECK_EQ(SEGV_ACCERR, last_code);
102
}
103
104
ATF_TC_WITHOUT_HEAD(page_fault_signal__segv_accerr_2);
105
ATF_TC_BODY(page_fault_signal__segv_accerr_2, tc)
106
{
107
int *p;
108
int sz;
109
110
sz = getpagesize();
111
p = mmap(NULL, sz, PROT_NONE, MAP_ANON, -1, 0);
112
ATF_REQUIRE(p != MAP_FAILED);
113
if (sigsetjmp(sig_env, 1) == 0) {
114
setup_signals();
115
(void)*(volatile int *)p;
116
}
117
(void)munmap(p, sz);
118
ATF_CHECK_EQ(SIGSEGV, last_sig);
119
ATF_CHECK_EQ(SEGV_ACCERR, last_code);
120
}
121
122
ATF_TC_WITHOUT_HEAD(page_fault_signal__bus_objerr_1);
123
ATF_TC_BODY(page_fault_signal__bus_objerr_1, tc)
124
{
125
int *p;
126
int fd;
127
int sz;
128
129
sz = getpagesize();
130
fd = shm_open(SHM_ANON, O_RDWR | O_CREAT, 0600);
131
ATF_REQUIRE(fd != -1);
132
p = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
133
ATF_REQUIRE(p != MAP_FAILED);
134
if (sigsetjmp(sig_env, 1) == 0) {
135
setup_signals();
136
*(volatile int *)p = 1;
137
}
138
(void)munmap(p, sz);
139
(void)close(fd);
140
ATF_CHECK_EQ(SIGBUS, last_sig);
141
ATF_CHECK_EQ(BUS_OBJERR, last_code);
142
}
143
144
ATF_TC_WITHOUT_HEAD(page_fault_signal__bus_objerr_2);
145
ATF_TC_BODY(page_fault_signal__bus_objerr_2, tc)
146
{
147
int *p;
148
int fd;
149
int r;
150
int sz;
151
152
sz = getpagesize();
153
fd = shm_open(SHM_ANON, O_RDWR | O_CREAT, 0600);
154
ATF_REQUIRE(fd != -1);
155
r = ftruncate(fd, sz);
156
ATF_REQUIRE(r != -1);
157
p = mmap(NULL, sz * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
158
ATF_REQUIRE(p != MAP_FAILED);
159
if (sigsetjmp(sig_env, 1) == 0) {
160
setup_signals();
161
((volatile int *)p)[sz / sizeof(int)] = 1;
162
}
163
(void)munmap(p, sz * 2);
164
(void)close(fd);
165
ATF_CHECK_EQ(SIGBUS, last_sig);
166
ATF_CHECK_EQ(BUS_OBJERR, last_code);
167
}
168
169
ATF_TP_ADD_TCS(tp)
170
{
171
172
ATF_TP_ADD_TC(tp, page_fault_signal__segv_maperr_1);
173
ATF_TP_ADD_TC(tp, page_fault_signal__segv_accerr_1);
174
ATF_TP_ADD_TC(tp, page_fault_signal__segv_accerr_2);
175
ATF_TP_ADD_TC(tp, page_fault_signal__bus_objerr_1);
176
ATF_TP_ADD_TC(tp, page_fault_signal__bus_objerr_2);
177
178
return (atf_no_error());
179
}
180
181