2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
12 * Copyright 2015 Alex Wilson, the University of Queensland
13 * Use is subject to license terms.
17 * Support functions for stack smashing protection (-fstack-protector
20 * The principle behind SSP is to place a "canary" value on the stack
21 * just below the arguments to a given function (which are in turn
22 * below the previous %rbp and return pointer). We write it onto the
23 * stack at the start of a function, and then at the end just before
24 * we execute "leave" and "ret", we check that the value is still there.
26 * If the check fails, we jump immediately to a handler (which typically
27 * just executes panic() straight away).
29 * Since an attacker will not know the value of the "canary", they will
30 * not be able to repair it correctly when overwriting the stack (and in
31 * almost all cases they must overwrite the canary to get to the return
32 * pointer), and the check will fail (and safely panic) instead of
33 * letting them gain control over %rip in a kernel thread.
35 * To debugging tools the canary just looks like another local variable
36 * (since it's placed below the normal argument space), and so there
37 * should be minimal/no impact on things that try to parse the
40 * Of course, adding these guards to every single function does not come
41 * without a price in performance, so normally only a subset of functions
42 * in a given program are guarded. Selecting which subset, and adding the
43 * guards is all handled automatically by the compiler.
45 * There are 3 (or 4) major relevant compiler options in GCC:
47 * * -fstack-protector-strong (only in GCC >= 4.9)
48 * * -fstack-protector-all
49 * * -fno-stack-protector
51 * The only differences between -fstack-protector, -strong and -all is in
52 * which functions are selected for adding guards.
54 * -fstack-protector adds guards to functions that make use of a stack-
55 * allocated char array (or aggregate containing one) of at least 8 bytes
58 * -fstack-protector-strong adds guards everywhere -fstack-protector
59 * does, and also adds guards to all functions that take or pass an address
60 * to a stack-allocated array of any type (eg arr, &arr[1] etc), as well as
61 * functions containing certain kinds of pointer arithmetic.
63 * -fstack-protector-all (as the name suggests) adds guards to every single
66 * There is also another variant, in the ProPolice patches which are used
67 * by some members of the BSD family (eg OpenBSD), which also guards any
68 * functions that store function pointers on the stack, as well as a few
69 * other heuristics (like re-ordering variables so arrays are as close as
70 * possible to the canary)
73 #include <sys/types.h>
74 #include <sys/cmn_err.h>
79 * The symbol __stack_chk_guard contains the magic guard value used
80 * to check stack integrity before returning from selected functions.
82 * Its value is set at startup to a "random" number -- this does not have
83 * to be cryptographically secure, but it does have to be done before
84 * calling any C functions that the stack guards may have been generated
87 * For this reason, the uts/i86pc/os directory is always built *without*
88 * stack protection enabled so that we can bootstrap.
91 uintptr_t __stack_chk_guard
= 0;
94 * The function __stack_chk_fail is called whenever a guard check fails.
97 __stack_chk_fail(void)
100 * Currently we just panic, but some more debug info could be useful.
101 * Note that we absolutely cannot trust any part of our stack at this
102 * point (we already know there's an attack in progress).
104 panic("Stack smashing detected");
107 static void salsa_hash(unsigned int *);
110 extern uint64_t ultra_gettick(void);
111 #define SSP_GET_TICK ultra_gettick
113 extern hrtime_t
tsc_read(void);
114 #define SSP_GET_TICK tsc_read
117 /* called from os/startup.c */
123 if (__stack_chk_guard
== 0) {
125 unsigned int state
[16];
130 for (i
= 0; i
< 8; ++i
)
131 s
.ts
[i
] = SSP_GET_TICK();
135 __stack_chk_guard
= s
.g
;
140 * Stealing the chacha/salsa hash function. It's simple, fast and
141 * public domain. We don't need/want the full cipher (which would
142 * belong in crypto) and we can't use the fully fledged PRNG
143 * framework either, since ssp_init has to be called extremely
146 * Since we don't have to be cryptographically secure, just using
147 * this to hash some high res timer values should be good enough.
149 #define QR(a, b, c, d) do { \
150 a += b; d ^= a; d <<= 16; \
151 c += d; b ^= c; b <<= 12; \
152 a += b; d ^= a; d <<= 8; \
153 c += d; b ^= c; b <<= 7; \
154 _NOTE(CONSTANTCONDITION) \
158 salsa_dr(unsigned int *state
)
160 QR(state
[0], state
[4], state
[ 8], state
[12]);
161 QR(state
[1], state
[5], state
[ 9], state
[13]);
162 QR(state
[2], state
[6], state
[10], state
[14]);
163 QR(state
[3], state
[7], state
[11], state
[15]);
164 QR(state
[0], state
[5], state
[10], state
[15]);
165 QR(state
[1], state
[6], state
[11], state
[12]);
166 QR(state
[2], state
[7], state
[ 8], state
[13]);
167 QR(state
[3], state
[4], state
[ 9], state
[14]);
171 salsa_hash(unsigned int *state
)
173 /* 10x applications of salsa doubleround */