]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/stack_protector.c
Reduce umtx-related work on exec and exit
[FreeBSD/FreeBSD.git] / sys / kern / stack_protector.c
1 #include <sys/cdefs.h>
2 __FBSDID("$FreeBSD$");
3
4 #include <sys/types.h>
5 #include <sys/param.h>
6 #include <sys/kernel.h>
7 #include <sys/random.h>
8 #include <sys/sysctl.h>
9 #include <sys/systm.h>
10 #include <sys/libkern.h>
11
12 long __stack_chk_guard[8] = {};
13 void __stack_chk_fail(void);
14
15 /*
16  * XXX This default is unsafe!!!  We intend to change it after resolving issues
17  * with early entropy in the installer; some kinds of systems that do not use
18  * loader(8), such as riscv, aarch64, and power; and perhaps others that I am
19  * forgetting off the top of my head.
20  */
21 static bool permit_nonrandom_cookies = true;
22
23 SYSCTL_NODE(_security, OID_AUTO, stack_protect, CTLFLAG_RW, 0,
24     "-fstack-protect support");
25 SYSCTL_BOOL(_security_stack_protect, OID_AUTO, permit_nonrandom_cookies,
26     CTLFLAG_RDTUN, &permit_nonrandom_cookies, 0,
27     "Allow stack guard to be used without real random cookies");
28
29 void
30 __stack_chk_fail(void)
31 {
32
33         panic("stack overflow detected; backtrace may be corrupted");
34 }
35
36 static void
37 __stack_chk_init(void *dummy __unused)
38 {
39         size_t i;
40         long guard[nitems(__stack_chk_guard)];
41
42         if (is_random_seeded()) {
43                 arc4rand(guard, sizeof(guard), 0);
44                 for (i = 0; i < nitems(guard); i++)
45                         __stack_chk_guard[i] = guard[i];
46                 return;
47         }
48
49         if (permit_nonrandom_cookies) {
50                 printf("%s: WARNING: Initializing stack protection with "
51                     "non-random cookies!\n", __func__);
52                 printf("%s: WARNING: This severely limits the benefit of "
53                     "-fstack-protector!\n", __func__);
54
55                 /*
56                  * The emperor is naked, but I rolled some dice and at least
57                  * these values aren't zero.
58                  */
59                 __stack_chk_guard[0] = (long)0xe7318d5959af899full;
60                 __stack_chk_guard[1] = (long)0x35a9481c089348bfull;
61                 __stack_chk_guard[2] = (long)0xde657fdc04117255ull;
62                 __stack_chk_guard[3] = (long)0x0dd44c61c22e4a6bull;
63                 __stack_chk_guard[4] = (long)0x0a5869a354edb0a5ull;
64                 __stack_chk_guard[5] = (long)0x05cebfed255b5232ull;
65                 __stack_chk_guard[6] = (long)0x270ffac137c4c72full;
66                 __stack_chk_guard[7] = (long)0xd8141a789bad478dull;
67                 _Static_assert(nitems(__stack_chk_guard) == 8,
68                     "__stack_chk_guard doesn't have 8 items");
69                 return;
70         }
71
72         panic("%s: cannot initialize stack cookies because random device is "
73             "not yet seeded", __func__);
74 }
75 SYSINIT(stack_chk, SI_SUB_RANDOM, SI_ORDER_ANY, __stack_chk_init, NULL);