1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker * All rights reserved.
4*795d594fSAndroid Build Coastguard Worker *
5*795d594fSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*795d594fSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
7*795d594fSAndroid Build Coastguard Worker * are met:
8*795d594fSAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright
9*795d594fSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
10*795d594fSAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright
11*795d594fSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in
12*795d594fSAndroid Build Coastguard Worker * the documentation and/or other materials provided with the
13*795d594fSAndroid Build Coastguard Worker * distribution.
14*795d594fSAndroid Build Coastguard Worker *
15*795d594fSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16*795d594fSAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17*795d594fSAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18*795d594fSAndroid Build Coastguard Worker * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19*795d594fSAndroid Build Coastguard Worker * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20*795d594fSAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21*795d594fSAndroid Build Coastguard Worker * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22*795d594fSAndroid Build Coastguard Worker * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23*795d594fSAndroid Build Coastguard Worker * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*795d594fSAndroid Build Coastguard Worker * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25*795d594fSAndroid Build Coastguard Worker * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*795d594fSAndroid Build Coastguard Worker * SUCH DAMAGE.
27*795d594fSAndroid Build Coastguard Worker */
28*795d594fSAndroid Build Coastguard Worker
29*795d594fSAndroid Build Coastguard Worker #include <dlfcn.h>
30*795d594fSAndroid Build Coastguard Worker #include <pthread.h>
31*795d594fSAndroid Build Coastguard Worker #include <signal.h>
32*795d594fSAndroid Build Coastguard Worker #include <sys/syscall.h>
33*795d594fSAndroid Build Coastguard Worker
34*795d594fSAndroid Build Coastguard Worker #include <functional>
35*795d594fSAndroid Build Coastguard Worker
36*795d594fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
37*795d594fSAndroid Build Coastguard Worker
38*795d594fSAndroid Build Coastguard Worker #include "sigchain.h"
39*795d594fSAndroid Build Coastguard Worker
40*795d594fSAndroid Build Coastguard Worker #if defined(__clang__) && __has_feature(hwaddress_sanitizer)
41*795d594fSAndroid Build Coastguard Worker #define DISABLE_HWASAN __attribute__((no_sanitize("hwaddress")))
42*795d594fSAndroid Build Coastguard Worker #else
43*795d594fSAndroid Build Coastguard Worker #define DISABLE_HWASAN
44*795d594fSAndroid Build Coastguard Worker #endif
45*795d594fSAndroid Build Coastguard Worker
46*795d594fSAndroid Build Coastguard Worker #if !defined(__BIONIC__)
47*795d594fSAndroid Build Coastguard Worker using sigset64_t = sigset_t;
48*795d594fSAndroid Build Coastguard Worker
sigemptyset64(sigset64_t * set)49*795d594fSAndroid Build Coastguard Worker static int sigemptyset64(sigset64_t* set) {
50*795d594fSAndroid Build Coastguard Worker return sigemptyset(set);
51*795d594fSAndroid Build Coastguard Worker }
52*795d594fSAndroid Build Coastguard Worker
sigismember64(sigset64_t * set,int member)53*795d594fSAndroid Build Coastguard Worker static int sigismember64(sigset64_t* set, int member) {
54*795d594fSAndroid Build Coastguard Worker return sigismember(set, member);
55*795d594fSAndroid Build Coastguard Worker }
56*795d594fSAndroid Build Coastguard Worker #endif
57*795d594fSAndroid Build Coastguard Worker
RealSigprocmask(int how,const sigset64_t * new_sigset,sigset64_t * old_sigset)58*795d594fSAndroid Build Coastguard Worker static int RealSigprocmask(int how, const sigset64_t* new_sigset, sigset64_t* old_sigset) {
59*795d594fSAndroid Build Coastguard Worker // glibc's sigset_t is overly large, so sizeof(*new_sigset) doesn't work.
60*795d594fSAndroid Build Coastguard Worker return syscall(__NR_rt_sigprocmask, how, new_sigset, old_sigset, NSIG/8);
61*795d594fSAndroid Build Coastguard Worker }
62*795d594fSAndroid Build Coastguard Worker
63*795d594fSAndroid Build Coastguard Worker class SigchainTest : public ::testing::Test {
SetUp()64*795d594fSAndroid Build Coastguard Worker void SetUp() final {
65*795d594fSAndroid Build Coastguard Worker art::AddSpecialSignalHandlerFn(SIGSEGV, &action);
66*795d594fSAndroid Build Coastguard Worker }
67*795d594fSAndroid Build Coastguard Worker
TearDown()68*795d594fSAndroid Build Coastguard Worker void TearDown() final {
69*795d594fSAndroid Build Coastguard Worker art::RemoveSpecialSignalHandlerFn(SIGSEGV, action.sc_sigaction);
70*795d594fSAndroid Build Coastguard Worker }
71*795d594fSAndroid Build Coastguard Worker
72*795d594fSAndroid Build Coastguard Worker art::SigchainAction action = {
__anon4261b3b00102() 73*795d594fSAndroid Build Coastguard Worker .sc_sigaction = [](int, siginfo_t* info, void*) -> bool {
74*795d594fSAndroid Build Coastguard Worker return info->si_value.sival_ptr;
75*795d594fSAndroid Build Coastguard Worker },
__anon4261b3b00202() 76*795d594fSAndroid Build Coastguard Worker .sc_mask = {},
77*795d594fSAndroid Build Coastguard Worker .sc_flags = 0,
78*795d594fSAndroid Build Coastguard Worker };
79*795d594fSAndroid Build Coastguard Worker
80*795d594fSAndroid Build Coastguard Worker protected:
RaiseHandled()81*795d594fSAndroid Build Coastguard Worker void RaiseHandled() {
82*795d594fSAndroid Build Coastguard Worker sigval value;
83*795d594fSAndroid Build Coastguard Worker value.sival_ptr = &value;
84*795d594fSAndroid Build Coastguard Worker // pthread_sigqueue would guarantee the signal is delivered to this
85*795d594fSAndroid Build Coastguard Worker // thread, but it is a nonstandard extension and does not exist in
86*795d594fSAndroid Build Coastguard Worker // musl. Gtest is single threaded, and these tests don't create any
87*795d594fSAndroid Build Coastguard Worker // threads, so sigqueue can be used and will deliver to this thread.
88*795d594fSAndroid Build Coastguard Worker sigqueue(getpid(), SIGSEGV, value);
89*795d594fSAndroid Build Coastguard Worker }
90*795d594fSAndroid Build Coastguard Worker
RaiseUnhandled()91*795d594fSAndroid Build Coastguard Worker void RaiseUnhandled() {
92*795d594fSAndroid Build Coastguard Worker sigval value;
93*795d594fSAndroid Build Coastguard Worker value.sival_ptr = nullptr;
94*795d594fSAndroid Build Coastguard Worker sigqueue(getpid(), SIGSEGV, value);
95*795d594fSAndroid Build Coastguard Worker }
96*795d594fSAndroid Build Coastguard Worker };
97*795d594fSAndroid Build Coastguard Worker
98*795d594fSAndroid Build Coastguard Worker
TestSignalBlocking(const std::function<void ()> & fn)99*795d594fSAndroid Build Coastguard Worker static void TestSignalBlocking(const std::function<void()>& fn) {
100*795d594fSAndroid Build Coastguard Worker // Unblock SIGSEGV, make sure it stays unblocked.
101*795d594fSAndroid Build Coastguard Worker sigset64_t mask;
102*795d594fSAndroid Build Coastguard Worker sigemptyset64(&mask);
103*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, RealSigprocmask(SIG_SETMASK, &mask, nullptr)) << strerror(errno);
104*795d594fSAndroid Build Coastguard Worker
105*795d594fSAndroid Build Coastguard Worker fn();
106*795d594fSAndroid Build Coastguard Worker
107*795d594fSAndroid Build Coastguard Worker if (testing::Test::HasFatalFailure()) return;
108*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, RealSigprocmask(SIG_SETMASK, nullptr, &mask));
109*795d594fSAndroid Build Coastguard Worker ASSERT_FALSE(sigismember64(&mask, SIGSEGV));
110*795d594fSAndroid Build Coastguard Worker }
111*795d594fSAndroid Build Coastguard Worker
TEST_F(SigchainTest,sigprocmask_setmask)112*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, sigprocmask_setmask) {
113*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
114*795d594fSAndroid Build Coastguard Worker sigset_t mask;
115*795d594fSAndroid Build Coastguard Worker sigfillset(&mask);
116*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &mask, nullptr));
117*795d594fSAndroid Build Coastguard Worker });
118*795d594fSAndroid Build Coastguard Worker }
119*795d594fSAndroid Build Coastguard Worker
TEST_F(SigchainTest,sigprocmask_block)120*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, sigprocmask_block) {
121*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
122*795d594fSAndroid Build Coastguard Worker sigset_t mask;
123*795d594fSAndroid Build Coastguard Worker sigfillset(&mask);
124*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &mask, nullptr));
125*795d594fSAndroid Build Coastguard Worker });
126*795d594fSAndroid Build Coastguard Worker }
127*795d594fSAndroid Build Coastguard Worker
128*795d594fSAndroid Build Coastguard Worker // bionic-only wide variants for LP32.
129*795d594fSAndroid Build Coastguard Worker #if defined(__BIONIC__)
TEST_F(SigchainTest,sigprocmask64_setmask)130*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, sigprocmask64_setmask) {
131*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
132*795d594fSAndroid Build Coastguard Worker sigset64_t mask;
133*795d594fSAndroid Build Coastguard Worker sigfillset64(&mask);
134*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, sigprocmask64(SIG_SETMASK, &mask, nullptr));
135*795d594fSAndroid Build Coastguard Worker });
136*795d594fSAndroid Build Coastguard Worker }
137*795d594fSAndroid Build Coastguard Worker
TEST_F(SigchainTest,sigprocmask64_block)138*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, sigprocmask64_block) {
139*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
140*795d594fSAndroid Build Coastguard Worker sigset64_t mask;
141*795d594fSAndroid Build Coastguard Worker sigfillset64(&mask);
142*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, sigprocmask64(SIG_BLOCK, &mask, nullptr));
143*795d594fSAndroid Build Coastguard Worker });
144*795d594fSAndroid Build Coastguard Worker }
145*795d594fSAndroid Build Coastguard Worker
TEST_F(SigchainTest,pthread_sigmask64_setmask)146*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, pthread_sigmask64_setmask) {
147*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
148*795d594fSAndroid Build Coastguard Worker sigset64_t mask;
149*795d594fSAndroid Build Coastguard Worker sigfillset64(&mask);
150*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, pthread_sigmask64(SIG_SETMASK, &mask, nullptr));
151*795d594fSAndroid Build Coastguard Worker });
152*795d594fSAndroid Build Coastguard Worker }
153*795d594fSAndroid Build Coastguard Worker
TEST_F(SigchainTest,pthread_sigmask64_block)154*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, pthread_sigmask64_block) {
155*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
156*795d594fSAndroid Build Coastguard Worker sigset64_t mask;
157*795d594fSAndroid Build Coastguard Worker sigfillset64(&mask);
158*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, pthread_sigmask64(SIG_BLOCK, &mask, nullptr));
159*795d594fSAndroid Build Coastguard Worker });
160*795d594fSAndroid Build Coastguard Worker }
161*795d594fSAndroid Build Coastguard Worker #endif
162*795d594fSAndroid Build Coastguard Worker
163*795d594fSAndroid Build Coastguard Worker // glibc doesn't implement most of these in terms of sigprocmask, which we rely on.
164*795d594fSAndroid Build Coastguard Worker #if defined(__BIONIC__)
TEST_F(SigchainTest,pthread_sigmask_setmask)165*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, pthread_sigmask_setmask) {
166*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
167*795d594fSAndroid Build Coastguard Worker sigset_t mask;
168*795d594fSAndroid Build Coastguard Worker sigfillset(&mask);
169*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, pthread_sigmask(SIG_SETMASK, &mask, nullptr));
170*795d594fSAndroid Build Coastguard Worker });
171*795d594fSAndroid Build Coastguard Worker }
172*795d594fSAndroid Build Coastguard Worker
TEST_F(SigchainTest,pthread_sigmask_block)173*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, pthread_sigmask_block) {
174*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
175*795d594fSAndroid Build Coastguard Worker sigset_t mask;
176*795d594fSAndroid Build Coastguard Worker sigfillset(&mask);
177*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, pthread_sigmask(SIG_BLOCK, &mask, nullptr));
178*795d594fSAndroid Build Coastguard Worker });
179*795d594fSAndroid Build Coastguard Worker }
180*795d594fSAndroid Build Coastguard Worker
TEST_F(SigchainTest,sigset_mask)181*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, sigset_mask) {
182*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
183*795d594fSAndroid Build Coastguard Worker sigset(SIGSEGV, SIG_HOLD);
184*795d594fSAndroid Build Coastguard Worker });
185*795d594fSAndroid Build Coastguard Worker }
186*795d594fSAndroid Build Coastguard Worker
TEST_F(SigchainTest,sighold)187*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, sighold) {
188*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
189*795d594fSAndroid Build Coastguard Worker sighold(SIGSEGV);
190*795d594fSAndroid Build Coastguard Worker });
191*795d594fSAndroid Build Coastguard Worker }
192*795d594fSAndroid Build Coastguard Worker
193*795d594fSAndroid Build Coastguard Worker #if !defined(__riscv)
194*795d594fSAndroid Build Coastguard Worker // Not exposed via headers, but the symbols are available if you declare them yourself.
195*795d594fSAndroid Build Coastguard Worker extern "C" int sigblock(int);
TEST_F(SigchainTest,sigblock)196*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, sigblock) {
197*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
198*795d594fSAndroid Build Coastguard Worker int mask = ~0U;
199*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, sigblock(mask));
200*795d594fSAndroid Build Coastguard Worker });
201*795d594fSAndroid Build Coastguard Worker }
202*795d594fSAndroid Build Coastguard Worker extern "C" int sigsetmask(int);
TEST_F(SigchainTest,sigsetmask)203*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, sigsetmask) {
204*795d594fSAndroid Build Coastguard Worker TestSignalBlocking([]() {
205*795d594fSAndroid Build Coastguard Worker int mask = ~0U;
206*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, sigsetmask(mask));
207*795d594fSAndroid Build Coastguard Worker });
208*795d594fSAndroid Build Coastguard Worker }
209*795d594fSAndroid Build Coastguard Worker #endif
210*795d594fSAndroid Build Coastguard Worker
211*795d594fSAndroid Build Coastguard Worker #endif
212*795d594fSAndroid Build Coastguard Worker
213*795d594fSAndroid Build Coastguard Worker // Make sure that we properly put ourselves back in front if we get circumvented.
TEST_F(SigchainTest,EnsureFrontOfChain)214*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, EnsureFrontOfChain) {
215*795d594fSAndroid Build Coastguard Worker #if defined(__BIONIC__)
216*795d594fSAndroid Build Coastguard Worker constexpr char kLibcSoName[] = "libc.so";
217*795d594fSAndroid Build Coastguard Worker #elif defined(__GNU_LIBRARY__) && __GNU_LIBRARY__ == 6
218*795d594fSAndroid Build Coastguard Worker constexpr char kLibcSoName[] = "libc.so.6";
219*795d594fSAndroid Build Coastguard Worker #elif defined(ANDROID_HOST_MUSL)
220*795d594fSAndroid Build Coastguard Worker constexpr char kLibcSoName[] = "libc_musl.so";
221*795d594fSAndroid Build Coastguard Worker #else
222*795d594fSAndroid Build Coastguard Worker #error Unknown libc
223*795d594fSAndroid Build Coastguard Worker #endif
224*795d594fSAndroid Build Coastguard Worker void* libc = dlopen(kLibcSoName, RTLD_LAZY | RTLD_NOLOAD);
225*795d594fSAndroid Build Coastguard Worker ASSERT_TRUE(libc);
226*795d594fSAndroid Build Coastguard Worker
227*795d594fSAndroid Build Coastguard Worker auto libc_sigaction = reinterpret_cast<decltype(&sigaction)>(dlsym(libc, "sigaction"));
228*795d594fSAndroid Build Coastguard Worker ASSERT_TRUE(libc_sigaction);
229*795d594fSAndroid Build Coastguard Worker
230*795d594fSAndroid Build Coastguard Worker static sig_atomic_t called = 0;
231*795d594fSAndroid Build Coastguard Worker struct sigaction action = {};
232*795d594fSAndroid Build Coastguard Worker action.sa_flags = SA_SIGINFO;
233*795d594fSAndroid Build Coastguard Worker action.sa_sigaction = [](int, siginfo_t*, void*) { called = 1; };
234*795d594fSAndroid Build Coastguard Worker
235*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, libc_sigaction(SIGSEGV, &action, nullptr));
236*795d594fSAndroid Build Coastguard Worker
237*795d594fSAndroid Build Coastguard Worker // Try before EnsureFrontOfChain.
238*795d594fSAndroid Build Coastguard Worker RaiseHandled();
239*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(1, called);
240*795d594fSAndroid Build Coastguard Worker called = 0;
241*795d594fSAndroid Build Coastguard Worker
242*795d594fSAndroid Build Coastguard Worker RaiseUnhandled();
243*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(1, called);
244*795d594fSAndroid Build Coastguard Worker called = 0;
245*795d594fSAndroid Build Coastguard Worker
246*795d594fSAndroid Build Coastguard Worker // ...and after.
247*795d594fSAndroid Build Coastguard Worker art::EnsureFrontOfChain(SIGSEGV);
248*795d594fSAndroid Build Coastguard Worker RaiseHandled();
249*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, called);
250*795d594fSAndroid Build Coastguard Worker
251*795d594fSAndroid Build Coastguard Worker RaiseUnhandled();
252*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(1, called);
253*795d594fSAndroid Build Coastguard Worker called = 0;
254*795d594fSAndroid Build Coastguard Worker }
255*795d594fSAndroid Build Coastguard Worker
256*795d594fSAndroid Build Coastguard Worker #if defined(__aarch64__)
257*795d594fSAndroid Build Coastguard Worker // The test intentionally dereferences (tagged) null to trigger SIGSEGV.
258*795d594fSAndroid Build Coastguard Worker // We need to disable HWASAN since it would catch the dereference first.
fault_address_tag_impl()259*795d594fSAndroid Build Coastguard Worker DISABLE_HWASAN void fault_address_tag_impl() {
260*795d594fSAndroid Build Coastguard Worker struct sigaction action = {};
261*795d594fSAndroid Build Coastguard Worker action.sa_flags = SA_SIGINFO;
262*795d594fSAndroid Build Coastguard Worker action.sa_sigaction = [](int, siginfo_t* siginfo, void*) {
263*795d594fSAndroid Build Coastguard Worker _exit(reinterpret_cast<uintptr_t>(siginfo->si_addr) >> 56);
264*795d594fSAndroid Build Coastguard Worker };
265*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, sigaction(SIGSEGV, &action, nullptr));
266*795d594fSAndroid Build Coastguard Worker
267*795d594fSAndroid Build Coastguard Worker auto* tagged_null = reinterpret_cast<int*>(0x2bULL << 56);
268*795d594fSAndroid Build Coastguard Worker EXPECT_EXIT(
269*795d594fSAndroid Build Coastguard Worker { [[maybe_unused]] volatile int load = *tagged_null; }, testing::ExitedWithCode(0), "");
270*795d594fSAndroid Build Coastguard Worker
271*795d594fSAndroid Build Coastguard Worker // Our sigaction implementation always implements the "clear unknown bits"
272*795d594fSAndroid Build Coastguard Worker // semantics for oldact.sa_flags regardless of kernel version so we rely on it
273*795d594fSAndroid Build Coastguard Worker // here to test for kernel support for SA_EXPOSE_TAGBITS.
274*795d594fSAndroid Build Coastguard Worker action.sa_flags = SA_SIGINFO | SA_EXPOSE_TAGBITS;
275*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, sigaction(SIGSEGV, &action, nullptr));
276*795d594fSAndroid Build Coastguard Worker ASSERT_EQ(0, sigaction(SIGSEGV, nullptr, &action));
277*795d594fSAndroid Build Coastguard Worker if (action.sa_flags & SA_EXPOSE_TAGBITS) {
278*795d594fSAndroid Build Coastguard Worker EXPECT_EXIT({ [[maybe_unused]] volatile int load = *tagged_null; },
279*795d594fSAndroid Build Coastguard Worker testing::ExitedWithCode(0x2b),
280*795d594fSAndroid Build Coastguard Worker "");
281*795d594fSAndroid Build Coastguard Worker }
282*795d594fSAndroid Build Coastguard Worker }
283*795d594fSAndroid Build Coastguard Worker #endif
284*795d594fSAndroid Build Coastguard Worker
TEST_F(SigchainTest,fault_address_tag)285*795d594fSAndroid Build Coastguard Worker TEST_F(SigchainTest, fault_address_tag) {
286*795d594fSAndroid Build Coastguard Worker #define SA_EXPOSE_TAGBITS 0x00000800
287*795d594fSAndroid Build Coastguard Worker #if defined(__aarch64__)
288*795d594fSAndroid Build Coastguard Worker fault_address_tag_impl();
289*795d594fSAndroid Build Coastguard Worker #else
290*795d594fSAndroid Build Coastguard Worker GTEST_SKIP() << "arm64 only";
291*795d594fSAndroid Build Coastguard Worker #endif
292*795d594fSAndroid Build Coastguard Worker }
293