~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/sigaltstack/sas.c

Version: ~ [ linux-5.16-rc3 ] ~ [ linux-5.15.5 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.82 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.162 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.218 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.256 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.291 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.293 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /*
  3  * Stas Sergeev <stsp@users.sourceforge.net>
  4  *
  5  * test sigaltstack(SS_ONSTACK | SS_AUTODISARM)
  6  * If that succeeds, then swapcontext() can be used inside sighandler safely.
  7  *
  8  */
  9 
 10 #define _GNU_SOURCE
 11 #include <signal.h>
 12 #include <stdio.h>
 13 #include <stdlib.h>
 14 #include <sys/mman.h>
 15 #include <ucontext.h>
 16 #include <alloca.h>
 17 #include <string.h>
 18 #include <assert.h>
 19 #include <errno.h>
 20 
 21 #include "../kselftest.h"
 22 
 23 #ifndef SS_AUTODISARM
 24 #define SS_AUTODISARM  (1U << 31)
 25 #endif
 26 
 27 static void *sstack, *ustack;
 28 static ucontext_t uc, sc;
 29 static const char *msg = "[OK]\tStack preserved";
 30 static const char *msg2 = "[FAIL]\tStack corrupted";
 31 struct stk_data {
 32         char msg[128];
 33         int flag;
 34 };
 35 
 36 void my_usr1(int sig, siginfo_t *si, void *u)
 37 {
 38         char *aa;
 39         int err;
 40         stack_t stk;
 41         struct stk_data *p;
 42 
 43 #if __s390x__
 44         register unsigned long sp asm("%15");
 45 #else
 46         register unsigned long sp asm("sp");
 47 #endif
 48 
 49         if (sp < (unsigned long)sstack ||
 50                         sp >= (unsigned long)sstack + SIGSTKSZ) {
 51                 ksft_exit_fail_msg("SP is not on sigaltstack\n");
 52         }
 53         /* put some data on stack. other sighandler will try to overwrite it */
 54         aa = alloca(1024);
 55         assert(aa);
 56         p = (struct stk_data *)(aa + 512);
 57         strcpy(p->msg, msg);
 58         p->flag = 1;
 59         ksft_print_msg("[RUN]\tsignal USR1\n");
 60         err = sigaltstack(NULL, &stk);
 61         if (err) {
 62                 ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno));
 63                 exit(EXIT_FAILURE);
 64         }
 65         if (stk.ss_flags != SS_DISABLE)
 66                 ksft_test_result_fail("tss_flags=%x, should be SS_DISABLE\n",
 67                                 stk.ss_flags);
 68         else
 69                 ksft_test_result_pass(
 70                                 "sigaltstack is disabled in sighandler\n");
 71         swapcontext(&sc, &uc);
 72         ksft_print_msg("%s\n", p->msg);
 73         if (!p->flag) {
 74                 ksft_exit_skip("[RUN]\tAborting\n");
 75                 exit(EXIT_FAILURE);
 76         }
 77 }
 78 
 79 void my_usr2(int sig, siginfo_t *si, void *u)
 80 {
 81         char *aa;
 82         struct stk_data *p;
 83 
 84         ksft_print_msg("[RUN]\tsignal USR2\n");
 85         aa = alloca(1024);
 86         /* dont run valgrind on this */
 87         /* try to find the data stored by previous sighandler */
 88         p = memmem(aa, 1024, msg, strlen(msg));
 89         if (p) {
 90                 ksft_test_result_fail("sigaltstack re-used\n");
 91                 /* corrupt the data */
 92                 strcpy(p->msg, msg2);
 93                 /* tell other sighandler that his data is corrupted */
 94                 p->flag = 0;
 95         }
 96 }
 97 
 98 static void switch_fn(void)
 99 {
100         ksft_print_msg("[RUN]\tswitched to user ctx\n");
101         raise(SIGUSR2);
102         setcontext(&sc);
103 }
104 
105 int main(void)
106 {
107         struct sigaction act;
108         stack_t stk;
109         int err;
110 
111         ksft_print_header();
112 
113         sigemptyset(&act.sa_mask);
114         act.sa_flags = SA_ONSTACK | SA_SIGINFO;
115         act.sa_sigaction = my_usr1;
116         sigaction(SIGUSR1, &act, NULL);
117         act.sa_sigaction = my_usr2;
118         sigaction(SIGUSR2, &act, NULL);
119         sstack = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
120                       MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
121         if (sstack == MAP_FAILED) {
122                 ksft_exit_fail_msg("mmap() - %s\n", strerror(errno));
123                 return EXIT_FAILURE;
124         }
125 
126         err = sigaltstack(NULL, &stk);
127         if (err) {
128                 ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno));
129                 exit(EXIT_FAILURE);
130         }
131         if (stk.ss_flags == SS_DISABLE) {
132                 ksft_test_result_pass(
133                                 "Initial sigaltstack state was SS_DISABLE\n");
134         } else {
135                 ksft_exit_fail_msg("Initial sigaltstack state was %x; "
136                        "should have been SS_DISABLE\n", stk.ss_flags);
137                 return EXIT_FAILURE;
138         }
139 
140         stk.ss_sp = sstack;
141         stk.ss_size = SIGSTKSZ;
142         stk.ss_flags = SS_ONSTACK | SS_AUTODISARM;
143         err = sigaltstack(&stk, NULL);
144         if (err) {
145                 if (errno == EINVAL) {
146                         ksft_exit_skip(
147                                 "[NOTE]\tThe running kernel doesn't support SS_AUTODISARM\n");
148                         /*
149                          * If test cases for the !SS_AUTODISARM variant were
150                          * added, we could still run them.  We don't have any
151                          * test cases like that yet, so just exit and report
152                          * success.
153                          */
154                         return 0;
155                 } else {
156                         ksft_exit_fail_msg(
157                                 "sigaltstack(SS_ONSTACK | SS_AUTODISARM)  %s\n",
158                                         strerror(errno));
159                         return EXIT_FAILURE;
160                 }
161         }
162 
163         ustack = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
164                       MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
165         if (ustack == MAP_FAILED) {
166                 ksft_exit_fail_msg("mmap() - %s\n", strerror(errno));
167                 return EXIT_FAILURE;
168         }
169         getcontext(&uc);
170         uc.uc_link = NULL;
171         uc.uc_stack.ss_sp = ustack;
172         uc.uc_stack.ss_size = SIGSTKSZ;
173         makecontext(&uc, switch_fn, 0);
174         raise(SIGUSR1);
175 
176         err = sigaltstack(NULL, &stk);
177         if (err) {
178                 ksft_exit_fail_msg("sigaltstack() - %s\n", strerror(errno));
179                 exit(EXIT_FAILURE);
180         }
181         if (stk.ss_flags != SS_AUTODISARM) {
182                 ksft_exit_fail_msg("ss_flags=%x, should be SS_AUTODISARM\n",
183                                 stk.ss_flags);
184                 exit(EXIT_FAILURE);
185         }
186         ksft_test_result_pass(
187                         "sigaltstack is still SS_AUTODISARM after signal\n");
188 
189         ksft_exit_pass();
190         return 0;
191 }
192 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp