1 /* Test the stack guard.
2    Copyright (C) 2000-2022 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library 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 the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library;  if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #define _GNU_SOURCE
20 
21 #include <pthread.h>
22 #include <assert.h>
23 #include <unistd.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <stdio.h>
27 
28 size_t stacksize;
29 
30 void *
thr(void * arg)31 thr (void *arg)
32 {
33   int i;
34   char *foo;
35 
36   foo = alloca (3 * stacksize / 4);
37   for (i = 0; i < sizeof foo; i++)
38     foo[i] = -1;
39 
40   return (void *) 1;
41 }
42 
43 int
main(int argc,char * argv[])44 main (int argc, char *argv[])
45 {
46   error_t err;
47   pid_t child;
48 
49   child = fork ();
50   switch (child)
51     {
52     case -1:
53       error (1, errno, "fork");
54       break;
55 
56     case 0:
57       {
58 	pthread_attr_t attr;
59 	pthread_t tid;
60 	void *ret;
61 
62 	err = pthread_attr_init (&attr);
63 	assert_perror (err);
64 
65 	err = pthread_attr_getstacksize (&attr, &stacksize);
66 	assert_perror (err);
67 
68 	err = pthread_attr_setguardsize (&attr, stacksize / 2);
69 	if (err == ENOTSUP)
70 	  {
71 	    printf ("Stack guard attribute not supported.\n");
72 	    return 1;
73 	  }
74 	assert_perror (err);
75 
76 	err = pthread_create (&tid, &attr, thr, 0);
77 	assert_perror (err);
78 
79 	err = pthread_attr_destroy (&attr);
80 	assert_perror (err);
81 
82 	err = pthread_join (tid, &ret);
83 	/* Should never be successful.  */
84 	printf ("Thread did not segfault!?!\n");
85 	assert_perror (err);
86 	return 0;
87       }
88 
89     default:
90       {
91 	pid_t pid;
92 	int status;
93 
94 	pid = waitpid (child, &status, 0);
95 	printf ("pid = %d; child = %d; status = %d\n", pid, child, status);
96 	assert (pid == child);
97 	assert (status != 0);
98       }
99     }
100 
101   return 0;
102 }
103