]>
Commit | Line | Data |
---|---|---|
6b93dcbe SK |
1 | /* |
2 | * test_sigreceive - wait for signal and exit with value of it | |
3 | * | |
4 | * Written by Sami Kerola <kerolasa@iki.fi> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License as | |
8 | * published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it would be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License along | |
16 | * with this program; if not, write to the Free Software Foundation, Inc., | |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 | */ | |
19 | ||
20 | #include <err.h> | |
21 | #include <getopt.h> | |
22 | #include <pwd.h> | |
23 | #include <signal.h> | |
24 | #include <stdio.h> | |
25 | #include <stdlib.h> | |
26 | #include <sys/select.h> | |
27 | #include <sys/types.h> | |
28 | #include <unistd.h> | |
29 | ||
30 | #include "strutils.h" | |
31 | ||
32 | #define TEST_SIGRECEIVE_FAILURE 0 | |
33 | ||
34 | static void __attribute__((__noreturn__)) usage(FILE *out) | |
35 | { | |
36 | fputs("Usage: test_sigreceive [-s|--setuid <login|uid>]\n", out); | |
37 | exit(TEST_SIGRECEIVE_FAILURE); | |
38 | } | |
39 | ||
40 | static __attribute__((__noreturn__)) | |
558445c9 SK |
41 | void exiter(int signo __attribute__((__unused__)), |
42 | siginfo_t *info, | |
43 | void *context __attribute__((__unused__))) | |
6b93dcbe | 44 | { |
558445c9 SK |
45 | int ret = info->si_signo; |
46 | ||
4ec60626 BE |
47 | if (info->si_code == SI_QUEUE && info->si_value.sival_int != 0) |
48 | ret = info->si_value.sival_int; | |
558445c9 | 49 | _exit(ret); |
6b93dcbe SK |
50 | } |
51 | ||
52 | int main(int argc, char **argv) | |
53 | { | |
54 | struct sigaction sigact; | |
55 | fd_set rfds; | |
56 | struct timeval timeout; | |
57 | char *user = NULL; | |
58 | int c; | |
59 | ||
60 | static const struct option longopts[] = { | |
61 | {"setuid", required_argument, NULL, 's'}, | |
62 | {NULL, 0, NULL, 0} | |
63 | }; | |
64 | ||
65 | while ((c = getopt_long(argc, argv, "s:h", longopts, NULL)) != -1) | |
66 | switch (c) { | |
67 | case 's': | |
68 | user = optarg; | |
69 | break; | |
70 | case 'h': | |
71 | usage(stdout); | |
72 | default: | |
73 | usage(stderr); | |
74 | } | |
75 | ||
76 | if (user) { | |
77 | struct passwd *pw; | |
78 | uid_t uid; | |
79 | ||
80 | pw = getpwnam(user); | |
81 | if (pw) | |
82 | uid = pw->pw_uid; | |
83 | else | |
84 | uid = strtou32_or_err(user, "failed to parse uid"); | |
85 | if (setuid(uid) < 0) | |
86 | err(TEST_SIGRECEIVE_FAILURE, "setuid failed"); | |
87 | } | |
88 | ||
89 | sigemptyset(&sigact.sa_mask); | |
558445c9 SK |
90 | sigact.sa_flags = SA_SIGINFO; |
91 | sigact.sa_sigaction = exiter; | |
6b93dcbe SK |
92 | timeout.tv_sec = 5; |
93 | timeout.tv_usec = 0; | |
94 | ||
95 | sigaction(SIGINT, &sigact, NULL); | |
96 | sigaction(SIGQUIT, &sigact, NULL); | |
97 | sigaction(SIGILL, &sigact, NULL); | |
98 | #ifdef SIGTRAP | |
99 | sigaction(SIGTRAP, &sigact, NULL); | |
100 | #endif | |
101 | sigaction(SIGABRT, &sigact, NULL); | |
102 | #ifdef SIGIOT | |
103 | sigaction(SIGIOT, &sigact, NULL); | |
104 | #endif | |
105 | #ifdef SIGEMT | |
106 | sigaction(SIGEMT, &sigact, NULL); | |
107 | #endif | |
108 | #ifdef SIGBUS | |
109 | sigaction(SIGBUS, &sigact, NULL); | |
110 | #endif | |
111 | sigaction(SIGFPE, &sigact, NULL); | |
112 | sigaction(SIGUSR1, &sigact, NULL); | |
113 | sigaction(SIGSEGV, &sigact, NULL); | |
114 | sigaction(SIGUSR2, &sigact, NULL); | |
115 | sigaction(SIGPIPE, &sigact, NULL); | |
116 | sigaction(SIGALRM, &sigact, NULL); | |
117 | sigaction(SIGTERM, &sigact, NULL); | |
118 | #ifdef SIGSTKFLT | |
119 | sigaction(SIGSTKFLT, &sigact, NULL); | |
120 | #endif | |
121 | sigaction(SIGCHLD, &sigact, NULL); | |
122 | #ifdef SIGCLD | |
123 | sigaction(SIGCLD, &sigact, NULL); | |
124 | #endif | |
125 | sigaction(SIGCONT, &sigact, NULL); | |
126 | sigaction(SIGTSTP, &sigact, NULL); | |
127 | sigaction(SIGTTIN, &sigact, NULL); | |
128 | sigaction(SIGTTOU, &sigact, NULL); | |
129 | #ifdef SIGURG | |
130 | sigaction(SIGURG, &sigact, NULL); | |
131 | #endif | |
132 | #ifdef SIGXCPU | |
133 | sigaction(SIGXCPU, &sigact, NULL); | |
134 | #endif | |
135 | #ifdef SIGXFSZ | |
136 | sigaction(SIGXFSZ, &sigact, NULL); | |
137 | #endif | |
138 | #ifdef SIGVTALRM | |
139 | sigaction(SIGVTALRM, &sigact, NULL); | |
140 | #endif | |
141 | #ifdef SIGPROF | |
142 | sigaction(SIGPROF, &sigact, NULL); | |
143 | #endif | |
144 | #ifdef SIGWINCH | |
145 | sigaction(SIGWINCH, &sigact, NULL); | |
146 | #endif | |
147 | #ifdef SIGIO | |
148 | sigaction(SIGIO, &sigact, NULL); | |
149 | #endif | |
150 | #ifdef SIGPOLL | |
151 | sigaction(SIGPOLL, &sigact, NULL); | |
152 | #endif | |
153 | #ifdef SIGINFO | |
154 | sigaction(SIGINFO, &sigact, NULL); | |
155 | #endif | |
156 | #ifdef SIGLOST | |
157 | sigaction(SIGLOST, &sigact, NULL); | |
158 | #endif | |
159 | #ifdef SIGPWR | |
160 | sigaction(SIGPWR, &sigact, NULL); | |
161 | #endif | |
162 | #ifdef SIGUNUSED | |
163 | sigaction(SIGUNUSED, &sigact, NULL); | |
164 | #endif | |
165 | #ifdef SIGSYS | |
166 | sigaction(SIGSYS, &sigact, NULL); | |
167 | #endif | |
168 | #ifdef SIGRTMIN | |
169 | sigaction(SIGRTMIN, &sigact, NULL); | |
170 | sigaction(SIGRTMAX, &sigact, NULL); | |
171 | #endif | |
172 | /* Keep SIGHUP last, the bit it flips tells to check script the | |
173 | * helper is ready to be killed. */ | |
174 | sigaction(SIGHUP, &sigact, NULL); | |
175 | ||
176 | FD_ZERO(&rfds); | |
177 | FD_SET(STDIN_FILENO, &rfds); | |
178 | select(0, &rfds, NULL, NULL, &timeout); | |
179 | ||
558445c9 | 180 | exit(TEST_SIGRECEIVE_FAILURE); |
6b93dcbe | 181 | } |