1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * Test Name: sigalstack02
22 *
23 * Test Description:
24 * Verify that,
25 * 1. sigaltstack() fails and sets errno to EINVAL when "ss_flags" field
26 * pointed to by 'ss' contains invalid flags.
27 * 2. sigaltstack() fails and sets errno to ENOMEM when the size of alternate
28 * stack area is less than MINSIGSTKSZ.
29 *
30 * Expected Result:
31 * sigaltstack() should fail with return value -1 and set expected errno.
32 *
33 * Algorithm:
34 * Setup:
35 * Setup signal handling.
36 * Create temporary directory.
37 * Pause for SIGUSR1 if option specified.
38 *
39 * Test:
40 * Loop if the proper options are given.
41 * Execute system call
42 * Check return code, if system call failed (return=-1)
43 * if errno set == expected errno
44 * Issue sys call fails with expected return value and errno.
45 * Otherwise,
46 * Issue sys call fails with unexpected errno.
47 * Otherwise,
48 * Issue sys call returns unexpected value.
49 *
50 * Cleanup:
51 * Print errno log and/or timing stats if options given
52 * Delete the temporary directory(s)/file(s) created.
53 *
54 * Usage: <for command-line>
55 * sigaltstack02 [-c n] [-e] [-f] [-i n] [-I x] [-p x] [-t]
56 * where, -c n : Run n copies concurrently.
57 * -e : Turn on errno logging.
58 * -f : Turn off functionality Testing.
59 * -i n : Execute test n times.
60 * -I x : Execute test for x seconds.
61 * -P x : Pause for x seconds between iterations.
62 * -t : Turn on syscall timing.
63 *
64 * History
65 * 07/2001 John George
66 * -Ported
67 *
68 * Restrictions:
69 * This test should be executed by super-user (root) only.
70 */
71
72 #include <stdio.h>
73 #include <sys/types.h>
74 #include <unistd.h>
75 #include <signal.h>
76 #include <string.h>
77 #include <ucontext.h>
78 #include <errno.h>
79
80 #include "test.h"
81
82 #define INVAL_FLAGS 9999
83
84 char *TCID = "sigaltstack02";
85 int TST_TOTAL = 2;
86
87 stack_t sigstk; /* signal stack storing struct. */
88
89 void setup(void); /* Main setup function of test */
90 void cleanup(void); /* cleanup function for the test */
91
92 struct test_case_t { /* test case struct. to hold diff. test.conds */
93 int flag;
94 int size;
95 char *desc;
96 int exp_errno;
97 } Test_cases[] = {
98 {
99 INVAL_FLAGS, SIGSTKSZ, "Invalid Flag value", EINVAL},
100 /* use value low enough for all kernel versions
101 * avoid using MINSIGSTKSZ defined by glibc as it could be different
102 * from the one in kernel ABI
103 */
104 {
105 0, (2048 - 1), "alternate stack is < MINSIGSTKSZ", ENOMEM},
106 {
107 0, 0, NULL, 0}
108 };
109
main(int ac,char ** av)110 int main(int ac, char **av)
111 {
112 int lc;
113 char *test_desc; /* test specific error message */
114 int ind; /* counter to test different test conditions */
115
116 tst_parse_opts(ac, av, NULL, NULL);
117
118 setup();
119
120 for (lc = 0; TEST_LOOPING(lc); lc++) {
121
122 tst_count = 0;
123
124 for (ind = 0; Test_cases[ind].desc != NULL; ind++) {
125 sigstk.ss_size = Test_cases[ind].size;
126 sigstk.ss_flags = Test_cases[ind].flag;
127 test_desc = Test_cases[ind].desc;
128
129 /* Verify sigaltstack() fails and sets errno */
130 TEST(sigaltstack(&sigstk, NULL));
131
132 /* Check return code from sigaltstack() */
133 if (TEST_RETURN == -1) {
134 if (TEST_ERRNO ==
135 Test_cases[ind].exp_errno) {
136 tst_resm(TPASS, "stgaltstack() "
137 "fails, %s, errno:%d",
138 test_desc, TEST_ERRNO);
139 } else {
140 tst_resm(TFAIL, "sigaltstack() "
141 "fails, %s, errno:%d, "
142 "expected errno:%d",
143 test_desc, TEST_ERRNO,
144 Test_cases
145 [ind].exp_errno);
146 }
147 } else {
148 tst_resm(TFAIL, "sigaltstack() returned %ld, "
149 "expected -1, errno:%d", TEST_RETURN,
150 Test_cases[ind].exp_errno);
151 }
152 }
153 tst_count++; /* incr. TEST_LOOP counter */
154 }
155
156 cleanup();
157 tst_exit();
158
159 }
160
161 /*
162 * void
163 * setup() - performs all ONE TIME setup for this test.
164 * Allocate memory for the alternative stack.
165 */
setup(void)166 void setup(void)
167 {
168
169 tst_sig(FORK, DEF_HANDLER, cleanup);
170
171 TEST_PAUSE;
172
173 /* Allocate memory for the alternate stack */
174 if ((sigstk.ss_sp = malloc(SIGSTKSZ)) == NULL) {
175 tst_brkm(TFAIL, cleanup,
176 "could not allocate memory for the alternate stack");
177 }
178 }
179
180 /*
181 * void
182 * cleanup() - performs all ONE TIME cleanup for this test at
183 * completion or premature exit.
184 * Free the memory allocated for alternate stack.
185 */
cleanup(void)186 void cleanup(void)
187 {
188
189 free(sigstk.ss_sp);
190
191 }
192