]> gcc.gnu.org Git - gcc.git/blame - gcc/ada/doc/gnat_rm/security_hardening_features.rst
[Ada] Document control flow redundancy
[gcc.git] / gcc / ada / doc / gnat_rm / security_hardening_features.rst
CommitLineData
a23e0209
AO
1.. _Security_Hardening_Features:
2
3***************************
4Security Hardening Features
5***************************
6
7This chapter describes Ada extensions aimed at security hardening that
8are provided by GNAT.
9
10.. Register Scrubbing:
11
12Register Scrubbing
13==================
14
15GNAT can generate code to zero-out hardware registers before returning
16from a subprogram.
17
cf54619a 18It can be enabled with the :switch:`-fzero-call-used-regs` command-line
a23e0209
AO
19option, to affect all subprograms in a compilation, and with a
20:samp:`Machine_Attribute` pragma, to affect only specific subprograms.
21
22.. code-block:: ada
23
24 procedure Foo;
25 pragma Machine_Attribute (Foo, "zero_call_used_regs", "used");
26 -- Before returning, Foo scrubs only call-clobbered registers
27 -- that it uses itself.
28
29 function Bar return Integer;
30 pragma Machine_Attribute (Bar, "zero_call_used_regs", "all");
31 -- Before returning, Bar scrubs all call-clobbered registers.
32
33
cf54619a 34For usage and more details on the command-line option, and on the
a23e0209
AO
35``zero_call_used_regs`` attribute, see :title:`Using the GNU Compiler
36Collection (GCC)`.
37
38
39.. Stack Scrubbing:
40
41Stack Scrubbing
42===============
43
44GNAT can generate code to zero-out stack frames used by subprograms.
45
46It can be activated with the :samp:`Machine_Attribute` pragma, on
47specific subprograms and variables.
48
49.. code-block:: ada
50
51 function Foo returns Integer;
52 pragma Machine_Attribute (Foo, "strub");
53 -- Foo and its callers are modified so as to scrub the stack
54 -- space used by Foo after it returns.
55
56 procedure Bar;
57 pragma Machine_Attribute (Bar, "strub", "internal");
58 -- Bar is turned into a wrapper for its original body,
59 -- and they scrub the stack used by the original body.
60
61 Var : Integer;
62 pragma Machine_Attribute (Var, "strub");
63 -- Reading from Var in a subprogram enables stack scrubbing
64 -- of the stack space used by the subprogram.
65
66
cf54619a
AO
67There are also :switch:`-fstrub` command-line options to control
68default settings. For usage and more details on the command-line
69option, and on the ``strub`` attribute, see :title:`Using the GNU
70Compiler Collection (GCC)`.
a23e0209
AO
71
72Note that Ada secondary stacks are not scrubbed. The restriction
73``No_Secondary_Stack`` avoids their use, and thus their accidental
74preservation of data that should be scrubbed.
75
d235950e
AO
76Attributes ``Access`` and ``Unconstrained_Access`` of variables and
77constants with ``strub`` enabled require types with ``strub`` enabled;
78there is no way to express an access-to-strub type otherwise.
79``Unchecked_Access`` bypasses this constraint, but the resulting
80access type designates a non-strub type.
81
82.. code-block:: ada
83
84 VI : Integer;
85 XsVI : access Integer := VI'Access; -- Error.
86 UXsVI : access Integer := VI'Unchecked_Access; -- OK,
87 -- UXsVI.all does not enable strub in the enclosing subprogram.
88
89 type Strub_Int is new Integer;
90 pragma Machine_Attribute (Strub_Int, "strub");
91 VSI : Strub_Int;
92 XsVSI : access Strub_Int := VSI'Access; -- OK.
93 -- XsVSI.all enables strub in the enclosing subprogram.
94
95
96Every access-to-subprogram type, renaming, and overriding and
97overridden dispatching operations that may refer to a subprogram with
98an attribute-modified interface must be annotated with the same
99interface-modifying attribute. Access-to-subprogram types can be
100explicitly converted to different strub modes, as long as they are
101interface-compatible (i.e., adding or removing ``at-calls`` is not
102allowed). For example, a ``strub``-``disabled`` subprogram can be
103turned ``callable`` through such an explicit conversion:
104
105.. code-block:: ada
106
107 type TBar is access procedure;
108
109 type TBar_Callable is access procedure;
110 pragma Machine_Attribute (TBar_Callable, "strub", "callable");
111
112 Bar_Callable_Ptr : constant TBar_Callable
113 := TBar_Callable (TBar'(Bar'Access));
114
115 procedure Bar_Callable renames Bar_Callable_Ptr.all;
116 pragma Machine_Attribute (Bar_Callable, "strub", "callable");
117
118Note that the renaming declaration is expanded to a full subprogram
119body, it won't be just an alias. Only if it is inlined will it be as
120efficient as a call by dereferencing the access-to-subprogram constant
121Bar_Callable_Ptr.
95bb87b2
AO
122
123
124.. Hardened Conditionals:
125
126Hardened Conditionals
127=====================
128
cf54619a 129GNAT can harden conditionals to protect against control-flow attacks.
95bb87b2
AO
130
131This is accomplished by two complementary transformations, each
132activated by a separate command-line option.
133
cf54619a
AO
134The option :switch:`-fharden-compares` enables hardening of compares
135that compute results stored in variables, adding verification that the
95bb87b2
AO
136reversed compare yields the opposite result.
137
cf54619a
AO
138The option :switch:`-fharden-conditional-branches` enables hardening
139of compares that guard conditional branches, adding verification of
140the reversed compare to both execution paths.
95bb87b2
AO
141
142These transformations are introduced late in the compilation pipeline,
143long after boolean expressions are decomposed into separate compares,
144each one turned into either a conditional branch or a compare whose
145result is stored in a boolean variable or temporary. Compiler
146optimizations, if enabled, may also turn conditional branches into
70c947e4
AO
147stored compares, and vice-versa, or into operations with implied
148conditionals (e.g. MIN and MAX). Conditionals may also be optimized
95bb87b2
AO
149out entirely, if their value can be determined at compile time, and
150occasionally multiple compares can be combined into one.
151
152It is thus difficult to predict which of these two options will affect
153a specific compare operation expressed in source code. Using both
70c947e4
AO
154options ensures that every compare that is neither optimized out nor
155optimized into implied conditionals will be hardened.
95bb87b2
AO
156
157The addition of reversed compares can be observed by enabling the dump
cf54619a
AO
158files of the corresponding passes, through command-line options
159:switch:`-fdump-tree-hardcmp` and :switch:`-fdump-tree-hardcbr`,
160respectively.
95bb87b2
AO
161
162They are separate options, however, because of the significantly
163different performance impact of the hardening transformations.
d4fc83c6
AO
164
165
166.. Hardened Booleans:
167
168Hardened Booleans
169=================
170
171Ada has built-in support for introducing boolean types with
172alternative representations, using representation clauses:
173
174.. code-block:: ada
175
176 type HBool is new Boolean;
177 for HBool use (16#5a#, 16#a5#);
178 for HBool'Size use 8;
179
180When validity checking is enabled, the compiler will check that
181variables of such types hold values corresponding to the selected
182representations.
183
184There are multiple strategies for where to introduce validity checking
cf54619a
AO
185(see :switch:`-gnatV` options). Their goal is to guard against
186various kinds of programming errors, and GNAT strives to omit checks
187when program logic rules out an invalid value, and optimizers may
188further remove checks found to be redundant.
d4fc83c6
AO
189
190For additional hardening, the ``hardbool`` :samp:`Machine_Attribute`
191pragma can be used to annotate boolean types with representation
192clauses, so that expressions of such types used as conditions are
cf54619a 193checked even when compiling with :switch:`-gnatVT`.
d4fc83c6
AO
194
195.. code-block:: ada
196
197 pragma Machine_Attribute (HBool, "hardbool");
198
cf54619a
AO
199Note that :switch:`-gnatVn` will disable even ``hardbool`` testing.
200
201
202.. Control Flow Redundancy:
203
204Control Flow Redundancy
205=======================
206
207GNAT can guard against unexpected execution flows, such as branching
208into the middle of subprograms, as in Return Oriented Programming
209exploits.
210
211In units compiled with :switch:`-fharden-control-flow-redundancy`,
212subprograms are instrumented so that, every time they are called,
213basic blocks take note as control flows through them, and, before
214returning, subprograms verify that the taken notes are consistent with
215the control-flow graph.
216
217Functions with too many basic blocks, or with multiple return points,
218call a run-time function to perform the verification. Other functions
219perform the verification inline before returning.
220
221Optimizing the inlined verification can be quite time consuming, so
222the default upper limit for the inline mode is set at 16 blocks.
223Command-line option :switch:`--param hardcfr-max-inline-blocks=` can
224override it.
225
226Even though typically sparse control-flow graphs exhibit run-time
227verification time nearly proportional to the block count of a
228subprogram, it may become very significant for generated subprograms
229with thousands of blocks. Command-line option
230:switch:`--param hardcfr-max-blocks=` can set an upper limit for
231instrumentation.
232
233For each block that is marked as visited, the mechanism checks that at
234least one of its predecessors, and at least one of its successors, are
235also marked as visited. Verification is normally performed just
236before return, but when a nonreturning call or a tail-call opportunity
237is detected, verification is moved before that (presumed) final call.
238
239If an exception from a nonreturning call is handled by its caller,
240verification at the caller may run again if another verification point
241is reached. The additional verifications are desirable and benign.
242
243Conversely, since no verification is inserted before calls that are
244expected to return, if they never do, the caller's own
245verification-and-return points are never reached.
246
247Subprogram executions that complete by raising or propagating an
248exception also bypass verification-and-return points. A subprogram
249that can only complete by raising or propagating an exception may have
250instrumentation disabled altogether.
251
252The instrumentation for hardening with control flow redundancy can be
253observed in dump files generated by the command-line option
254:switch:`-fdump-tree-hardcfr`.
This page took 0.242602 seconds and 5 git commands to generate.