1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <errno.h>
18 #include <signal.h>
19 #include <sys/syscall.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 
23 #include <gtest/gtest.h>
24 
25 #include "ScopedSignalHandler.h"
26 
SIGNAL_MIN()27 static size_t SIGNAL_MIN() {
28   return 1; // Signals start at 1 (SIGHUP), not 0.
29 }
30 
SIGNAL_MAX()31 static size_t SIGNAL_MAX() {
32   size_t result = SIGRTMAX;
33 
34 #if defined(__BIONIC__) && !defined(__mips__) && !defined(__LP64__)
35   // 32-bit bionic's sigset_t is too small for ARM and x86: 32 bits instead of 64.
36   // This means you can't refer to any of the real-time signals.
37   // See http://b/3038348 and http://b/5828899.
38   result = 32;
39 #else
40   // Otherwise, C libraries should be perfectly capable of using their largest signal.
41   if (sizeof(sigset_t) * 8 < static_cast<size_t>(SIGRTMAX)) {
42     abort();
43   }
44 #endif
45 
46   return result;
47 }
48 
49 template <typename Fn>
TestSigSet1(Fn fn)50 static void TestSigSet1(Fn fn) {
51   // NULL sigset_t*.
52   sigset_t* set_ptr = NULL;
53   errno = 0;
54   ASSERT_EQ(-1, fn(set_ptr));
55   ASSERT_EQ(EINVAL, errno);
56 
57   // Non-NULL.
58   sigset_t set;
59   errno = 0;
60   ASSERT_EQ(0, fn(&set));
61   ASSERT_EQ(0, errno);
62 }
63 
64 template <typename Fn>
TestSigSet2(Fn fn)65 static void TestSigSet2(Fn fn) {
66   // NULL sigset_t*.
67   sigset_t* set_ptr = NULL;
68   errno = 0;
69   ASSERT_EQ(-1, fn(set_ptr, SIGSEGV));
70   ASSERT_EQ(EINVAL, errno);
71 
72   sigset_t set;
73   sigemptyset(&set);
74 
75   // Bad signal number: too small.
76   errno = 0;
77   ASSERT_EQ(-1, fn(&set, 0));
78   ASSERT_EQ(EINVAL, errno);
79 
80   // Bad signal number: too high.
81   errno = 0;
82   ASSERT_EQ(-1, fn(&set, SIGNAL_MAX() + 1));
83   ASSERT_EQ(EINVAL, errno);
84 
85   // Good signal numbers, low and high ends of range.
86   errno = 0;
87   ASSERT_EQ(0, fn(&set, SIGNAL_MIN()));
88   ASSERT_EQ(0, errno);
89   ASSERT_EQ(0, fn(&set, SIGNAL_MAX()));
90   ASSERT_EQ(0, errno);
91 }
92 
TEST(signal,sigismember_invalid)93 TEST(signal, sigismember_invalid) {
94   TestSigSet2(sigismember);
95 }
96 
TEST(signal,sigaddset_invalid)97 TEST(signal, sigaddset_invalid) {
98   TestSigSet2(sigaddset);
99 }
100 
TEST(signal,sigdelset_invalid)101 TEST(signal, sigdelset_invalid) {
102   TestSigSet2(sigdelset);
103 }
104 
TEST(signal,sigemptyset_invalid)105 TEST(signal, sigemptyset_invalid) {
106   TestSigSet1(sigemptyset);
107 }
108 
TEST(signal,sigfillset_invalid)109 TEST(signal, sigfillset_invalid) {
110   TestSigSet1(sigfillset);
111 }
112 
TEST(signal,raise_invalid)113 TEST(signal, raise_invalid) {
114   errno = 0;
115   ASSERT_EQ(-1, raise(-1));
116   ASSERT_EQ(EINVAL, errno);
117 }
118 
raise_in_signal_handler_helper(int signal_number)119 static void raise_in_signal_handler_helper(int signal_number) {
120   ASSERT_EQ(SIGALRM, signal_number);
121   static int count = 0;
122   if (++count == 1) {
123     raise(SIGALRM);
124   }
125 }
126 
TEST(signal,raise_in_signal_handler)127 TEST(signal, raise_in_signal_handler) {
128   ScopedSignalHandler ssh(SIGALRM, raise_in_signal_handler_helper);
129   raise(SIGALRM);
130 }
131 
HandleSIGALRM(int signal_number)132 static void HandleSIGALRM(int signal_number) {
133   ASSERT_EQ(SIGALRM, signal_number);
134 }
135 
TEST(signal,sigwait)136 TEST(signal, sigwait) {
137   ScopedSignalHandler ssh(SIGALRM, HandleSIGALRM);
138 
139   sigset_t wait_set;
140   sigemptyset(&wait_set);
141   sigaddset(&wait_set, SIGALRM);
142 
143   alarm(1);
144 
145   int received_signal;
146   errno = 0;
147   ASSERT_EQ(0, sigwait(&wait_set, &received_signal));
148   ASSERT_EQ(0, errno);
149   ASSERT_EQ(SIGALRM, received_signal);
150 }
151 
152 static int g_sigsuspend_test_helper_call_count = 0;
153 
SigSuspendTestHelper(int)154 static void SigSuspendTestHelper(int) {
155   ++g_sigsuspend_test_helper_call_count;
156 }
157 
TEST(signal,sigsuspend_sigpending)158 TEST(signal, sigsuspend_sigpending) {
159   // Block SIGALRM.
160   sigset_t just_SIGALRM;
161   sigemptyset(&just_SIGALRM);
162   sigaddset(&just_SIGALRM, SIGALRM);
163   sigset_t original_set;
164   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set));
165 
166   ScopedSignalHandler ssh(SIGALRM, SigSuspendTestHelper);
167 
168   // There should be no pending signals.
169   sigset_t pending;
170   sigemptyset(&pending);
171   ASSERT_EQ(0, sigpending(&pending));
172   for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) {
173     EXPECT_FALSE(sigismember(&pending, i)) << i;
174   }
175 
176   // Raise SIGALRM and check our signal handler wasn't called.
177   raise(SIGALRM);
178   ASSERT_EQ(0, g_sigsuspend_test_helper_call_count);
179 
180   // We should now have a pending SIGALRM but nothing else.
181   sigemptyset(&pending);
182   ASSERT_EQ(0, sigpending(&pending));
183   for (size_t i = SIGNAL_MIN(); i <= SIGNAL_MAX(); ++i) {
184     EXPECT_EQ((i == SIGALRM), sigismember(&pending, i));
185   }
186 
187   // Use sigsuspend to block everything except SIGALRM...
188   sigset_t not_SIGALRM;
189   sigfillset(&not_SIGALRM);
190   sigdelset(&not_SIGALRM, SIGALRM);
191   ASSERT_EQ(-1, sigsuspend(&not_SIGALRM));
192   ASSERT_EQ(EINTR, errno);
193   // ...and check that we now receive our pending SIGALRM.
194   ASSERT_EQ(1, g_sigsuspend_test_helper_call_count);
195 
196   // Restore the original set.
197   ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
198 }
199 
EmptySignalHandler(int)200 static void EmptySignalHandler(int) {}
EmptySignalAction(int,siginfo_t *,void *)201 static void EmptySignalAction(int, siginfo_t*, void*) {}
202 
TEST(signal,sigaction)203 TEST(signal, sigaction) {
204   // Both bionic and glibc set SA_RESTORER when talking to the kernel on arm,
205   // arm64, x86, and x86-64. The version of glibc we're using also doesn't
206   // define SA_RESTORER, but luckily it's the same value everywhere, and mips
207   // doesn't use the bit for anything.
208   static const unsigned sa_restorer = 0x4000000;
209 
210   // See what's currently set for SIGALRM.
211   struct sigaction original_sa;
212   memset(&original_sa, 0, sizeof(original_sa));
213   ASSERT_EQ(0, sigaction(SIGALRM, NULL, &original_sa));
214   ASSERT_TRUE(original_sa.sa_handler == NULL);
215   ASSERT_TRUE(original_sa.sa_sigaction == NULL);
216   ASSERT_EQ(0U, original_sa.sa_flags & ~sa_restorer);
217 
218   // Set a traditional sa_handler signal handler.
219   struct sigaction sa;
220   memset(&sa, 0, sizeof(sa));
221   sigaddset(&sa.sa_mask, SIGALRM);
222   sa.sa_flags = SA_ONSTACK;
223   sa.sa_handler = EmptySignalHandler;
224   ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL));
225 
226   // Check that we can read it back.
227   memset(&sa, 0, sizeof(sa));
228   ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa));
229   ASSERT_TRUE(sa.sa_handler == EmptySignalHandler);
230   ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler);
231   ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK), sa.sa_flags & ~sa_restorer);
232 
233   // Set a new-style sa_sigaction signal handler.
234   memset(&sa, 0, sizeof(sa));
235   sigaddset(&sa.sa_mask, SIGALRM);
236   sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
237   sa.sa_sigaction = EmptySignalAction;
238   ASSERT_EQ(0, sigaction(SIGALRM, &sa, NULL));
239 
240   // Check that we can read it back.
241   memset(&sa, 0, sizeof(sa));
242   ASSERT_EQ(0, sigaction(SIGALRM, NULL, &sa));
243   ASSERT_TRUE(sa.sa_sigaction == EmptySignalAction);
244   ASSERT_TRUE((void*) sa.sa_sigaction == (void*) sa.sa_handler);
245   ASSERT_EQ(static_cast<unsigned>(SA_ONSTACK | SA_SIGINFO), sa.sa_flags & ~sa_restorer);
246 
247   // Put everything back how it was.
248   ASSERT_EQ(0, sigaction(SIGALRM, &original_sa, NULL));
249 }
250 
TEST(signal,sys_signame)251 TEST(signal, sys_signame) {
252 #if defined(__BIONIC__)
253   ASSERT_TRUE(sys_signame[0] == NULL);
254   ASSERT_STREQ("HUP", sys_signame[SIGHUP]);
255 #else
256   GTEST_LOG_(INFO) << "This test does nothing.\n";
257 #endif
258 }
259 
TEST(signal,sys_siglist)260 TEST(signal, sys_siglist) {
261   ASSERT_TRUE(sys_siglist[0] == NULL);
262   ASSERT_STREQ("Hangup", sys_siglist[SIGHUP]);
263 }
264 
TEST(signal,limits)265 TEST(signal, limits) {
266   // This comes from the kernel.
267   ASSERT_EQ(32, __SIGRTMIN);
268 
269   // We reserve a non-zero number at the bottom for ourselves.
270   ASSERT_GT(SIGRTMIN, __SIGRTMIN);
271 
272   // MIPS has more signals than everyone else.
273 #if defined(__mips__)
274   ASSERT_EQ(128, __SIGRTMAX);
275 #else
276   ASSERT_EQ(64, __SIGRTMAX);
277 #endif
278 
279   // We don't currently reserve any at the top.
280   ASSERT_EQ(SIGRTMAX, __SIGRTMAX);
281 }
282 
283 static int g_sigqueue_signal_handler_call_count = 0;
284 
SigqueueSignalHandler(int signum,siginfo_t * info,void *)285 static void SigqueueSignalHandler(int signum, siginfo_t* info, void*) {
286   ASSERT_EQ(SIGALRM, signum);
287   ASSERT_EQ(SIGALRM, info->si_signo);
288   ASSERT_EQ(SI_QUEUE, info->si_code);
289   ASSERT_EQ(1, info->si_value.sival_int);
290   ++g_sigqueue_signal_handler_call_count;
291 }
292 
TEST(signal,sigqueue)293 TEST(signal, sigqueue) {
294   ScopedSignalHandler ssh(SIGALRM, SigqueueSignalHandler, SA_SIGINFO);
295   sigval_t sigval;
296   sigval.sival_int = 1;
297   errno = 0;
298   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
299   ASSERT_EQ(0, errno);
300   ASSERT_EQ(1, g_sigqueue_signal_handler_call_count);
301 }
302 
TEST(signal,sigwaitinfo)303 TEST(signal, sigwaitinfo) {
304   // Block SIGALRM.
305   sigset_t just_SIGALRM;
306   sigemptyset(&just_SIGALRM);
307   sigaddset(&just_SIGALRM, SIGALRM);
308   sigset_t original_set;
309   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set));
310 
311   // Raise SIGALRM.
312   sigval_t sigval;
313   sigval.sival_int = 1;
314   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
315 
316   // Get pending SIGALRM.
317   siginfo_t info;
318   errno = 0;
319   ASSERT_EQ(SIGALRM, sigwaitinfo(&just_SIGALRM, &info));
320   ASSERT_EQ(0, errno);
321   ASSERT_EQ(SIGALRM, info.si_signo);
322   ASSERT_EQ(1, info.si_value.sival_int);
323 
324   ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
325 }
326 
TEST(signal,sigtimedwait)327 TEST(signal, sigtimedwait) {
328   // Block SIGALRM.
329   sigset_t just_SIGALRM;
330   sigemptyset(&just_SIGALRM);
331   sigaddset(&just_SIGALRM, SIGALRM);
332   sigset_t original_set;
333   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set));
334 
335   // Raise SIGALRM.
336   sigval_t sigval;
337   sigval.sival_int = 1;
338   ASSERT_EQ(0, sigqueue(getpid(), SIGALRM, sigval));
339 
340   // Get pending SIGALRM.
341   siginfo_t info;
342   struct timespec timeout;
343   timeout.tv_sec = 2;
344   timeout.tv_nsec = 0;
345   errno = 0;
346   ASSERT_EQ(SIGALRM, sigtimedwait(&just_SIGALRM, &info, &timeout));
347   ASSERT_EQ(0, errno);
348 
349   ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
350 }
351 
NanoTime()352 static int64_t NanoTime() {
353   struct timespec t;
354   t.tv_sec = t.tv_nsec = 0;
355   clock_gettime(CLOCK_MONOTONIC, &t);
356   return static_cast<int64_t>(t.tv_sec) * 1000000000LL + t.tv_nsec;
357 }
358 
TEST(signal,sigtimedwait_timeout)359 TEST(signal, sigtimedwait_timeout) {
360   // Block SIGALRM.
361   sigset_t just_SIGALRM;
362   sigemptyset(&just_SIGALRM);
363   sigaddset(&just_SIGALRM, SIGALRM);
364   sigset_t original_set;
365   ASSERT_EQ(0, sigprocmask(SIG_BLOCK, &just_SIGALRM, &original_set));
366 
367   // Wait timeout.
368   int64_t start_time = NanoTime();
369   siginfo_t info;
370   struct timespec timeout;
371   timeout.tv_sec = 0;
372   timeout.tv_nsec = 1000000;
373   errno = 0;
374   ASSERT_EQ(-1, sigtimedwait(&just_SIGALRM, &info, &timeout));
375   ASSERT_EQ(EAGAIN, errno);
376   ASSERT_GE(NanoTime() - start_time, 1000000);
377 
378   ASSERT_EQ(0, sigprocmask(SIG_SETMASK, &original_set, NULL));
379 }
380 
381 #if defined(__BIONIC__)
TEST(signal,rt_tgsigqueueinfo)382 TEST(signal, rt_tgsigqueueinfo) {
383   // Test whether rt_tgsigqueueinfo allows sending arbitrary si_code values to self.
384   // If this fails, your kernel needs commit 66dd34a to be backported.
385   static constexpr char error_msg[] =
386     "\nPlease ensure that the following kernel patch has been applied:\n"
387     "* https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=66dd34ad31e5963d72a700ec3f2449291d322921\n";
388   static siginfo received;
389 
390   struct sigaction handler;
391   memset(&handler, 0, sizeof(handler));
392   handler.sa_sigaction = [](int, siginfo_t* siginfo, void*) { received = *siginfo; };
393   handler.sa_flags = SA_SIGINFO;
394 
395   ASSERT_EQ(0, sigaction(SIGUSR1, &handler, nullptr));
396 
397   siginfo sent;
398   memset(&sent, 0, sizeof(sent));
399 
400   sent.si_code = SI_TKILL;
401   ASSERT_EQ(0, syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), SIGUSR1, &sent))
402     << "rt_tgsigqueueinfo failed: " << strerror(errno) << error_msg;
403   ASSERT_EQ(sent.si_code, received.si_code) << "rt_tgsigqueueinfo modified si_code, expected "
404                                             << sent.si_code << ", received " << received.si_code
405                                             << error_msg;
406 
407   sent.si_code = SI_USER;
408   ASSERT_EQ(0, syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), SIGUSR1, &sent))
409     << "rt_tgsigqueueinfo failed: " << strerror(errno) << error_msg;
410   ASSERT_EQ(sent.si_code, received.si_code) << "rt_tgsigqueueinfo modified si_code, expected "
411                                             << sent.si_code << ", received " << received.si_code
412                                             << error_msg;
413 }
414 
415 #if defined(__arm__) || defined(__aarch64__) || defined(__i386__) || defined(__x86_64__)
TEST(signal,sigset_size)416 TEST(signal, sigset_size) {
417   // The setjmp implementations for ARM, AArch64, x86, and x86_64 assume that sigset_t can fit in a
418   // long. This is true because ARM and x86 have broken rt signal support, and AArch64 and x86_64
419   // both have a SIGRTMAX defined as 64.
420   static_assert(sizeof(sigset_t) <= sizeof(long), "sigset_t doesn't fit in a long");
421 }
422 
423 #endif
424 #endif
425