Skip to content

Commit 64454da

Browse files
cjdbhawkinsw
andauthored
[libcxx] reorganises the hardening documentation (#73159)
The reorganisation assists with identifying information that's relevant to the reader by using sections, note/warning blocks, and highlighted lists. Some rewording was necessary to fit the new structure and some to improve flow. Changes to the intention of the documentation have not been made. --------- Co-authored-by: Will Hawkins <[email protected]>
1 parent a93cacf commit 64454da

File tree

1 file changed

+65
-54
lines changed

1 file changed

+65
-54
lines changed

libcxx/docs/Hardening.rst

Lines changed: 65 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,61 +15,72 @@ assertions that prevent undefined behavior caused by violating preconditions of
1515
the standard library. Different hardening modes make different trade-offs
1616
between the amount of checking and runtime performance. The available hardening
1717
modes are:
18-
- fast mode;
19-
- extensive mode;
20-
- debug mode.
21-
22-
The fast mode contains a set of security-critical checks that can be done with
23-
relatively little overhead in constant time and are intended to be used in
24-
production. We recommend most projects to adopt the fast mode.
25-
26-
The extensive mode contains all the checks from the fast mode and additionally
27-
some checks for undefined behavior that incur relatively little overhead but
28-
aren't security-critical. While the performance penalty is somewhat more
29-
significant compared to the fast mode, the extensive mode is still intended to
30-
be usable in production.
31-
32-
The debug mode enables all the available checks in the library, including
33-
internal assertions, some of which might be very expensive. This mode is
34-
intended to be used for testing, not in production.
35-
36-
Vendors can set the default hardening mode by using the
37-
``LIBCXX_HARDENING_MODE`` variable at CMake configuration time with the possible
38-
values of ``none``, ``fast``, ``extensive`` and ``debug``. The default value is
39-
``none`` which doesn't enable any hardening checks (this mode is sometimes
40-
called the ``unchecked`` mode).
41-
42-
When hardening is enabled, the compiled library is built with the corresponding
43-
mode enabled, **and** user code will be built with the same mode enabled by
44-
default. If the mode is set to "none" at the CMake configuration time, the
45-
compiled library will not contain any assertions and the default when building
46-
user code will be to have assertions disabled. As a user, you can consult your
47-
vendor to know which level of hardening is enabled by default.
48-
49-
Furthermore, independently of any vendor-selected default, users can always
50-
control which level of hardening is enabled in their code by defining the macro
51-
``_LIBCPP_HARDENING_MODE`` before including any libc++ headers (preferably by
52-
passing ``-D_LIBCPP_HARDENING_MODE=X`` to the compiler). The macro can be
53-
set to one of the following possible values:
54-
55-
- ``_LIBCPP_HARDENING_MODE_NONE``;
56-
- ``_LIBCPP_HARDENING_MODE_FAST``;
57-
- ``_LIBCPP_HARDENING_MODE_EXTENSIVE``;
58-
- ``_LIBCPP_HARDENING_MODE_DEBUG``.
59-
60-
The exact numeric values of these macros are unspecified and users should not
61-
rely on them (e.g. expect the values to be sorted in any way).
62-
63-
Note that if the compiled library was built by the vendor with the hardening
64-
mode set to "none", functions compiled inside the static or shared library won't
65-
have any hardening enabled even if the user compiles with hardening enabled (the
66-
same is true for the inverse case where the static or shared library was
67-
compiled **with** hardening enabled but the user tries to disable it). However,
68-
most of the code in libc++ is in the headers, so the user-selected value for
69-
``_LIBCPP_HARDENING_MODE``, if any, will usually be respected.
70-
71-
Enabling hardening has no impact on the ABI.
18+
19+
- **Unchecked mode/none**, which disables all hardening checks.
20+
- **Fast mode**, which contains a set of security-critical checks that can be
21+
done with relatively little overhead in constant time and are intended to be
22+
used in production. We recommend most projects adopt this.
23+
- **Extensive mode**, which contains all the checks from fast mode and some
24+
additional checks for undefined behavior that incur relatively little overhead
25+
but aren't security-critical. Production builds requiring a broader set of
26+
checks than fast mode should consider enabling extensive mode. The additional
27+
rigour impacts performance more than fast mode: we recommend benchmarking to
28+
determine if that is acceptable for your program.
29+
- **Debug mode**, which enables all the available checks in the library,
30+
including internal assertions, some of which might be very expensive. This
31+
mode is intended to be used for testing, not in production.
32+
33+
.. note::
34+
35+
Enabling hardening has no impact on the ABI.
36+
37+
Notes for users
38+
---------------
39+
40+
As a libc++ user, consult with your vendor to determine the level of hardening
41+
enabled by default.
42+
43+
Users wishing for a different hardening level to their vendor default are able
44+
to control the level by passing **one** of the following options to the compiler:
45+
46+
- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE``
47+
- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST``
48+
- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE``
49+
- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG``
50+
51+
.. warning::
52+
53+
The exact numeric values of these macros are unspecified and users should not
54+
rely on them (e.g. expect the values to be sorted in any way).
55+
56+
.. warning::
57+
58+
If you would prefer to override the hardening level on a per-translation-unit
59+
basis, you must do so **before** including any headers to avoid `ODR issues`_.
60+
61+
.. _`ODR issues`: https://en.cppreference.com/w/cpp/language/definition#:~:text=is%20ill%2Dformed.-,One%20Definition%20Rule,-Only%20one%20definition
62+
63+
.. note::
64+
65+
Since the static and shared library components of libc++ are built by the
66+
vendor, setting this macro will have no impact on the hardening mode for the
67+
pre-built components. Most libc++ code is header-based, so a user-provided
68+
value for ``_LIBCPP_HARDENING_MODE`` will be mostly respected.
69+
70+
Notes for vendors
71+
-----------------
72+
73+
Vendors can set the default hardening mode by providing ``LIBCXX_HARDENING_MODE``
74+
as a configuration option, with the possible values of ``none``, ``fast``,
75+
``extensive`` and ``debug``. The default value is ``none`` which doesn't enable
76+
any hardening checks (this mode is sometimes called the ``unchecked`` mode).
77+
78+
This option controls both the hardening mode that the precompiled library is
79+
built with and the default hardening mode that users will build with. If set to
80+
``none``, the precompiled library will not contain any assertions, and user code
81+
will default to building without assertions.
7282

7383
Iterator bounds checking
7484
------------------------
85+
7586
TODO(hardening)

0 commit comments

Comments
 (0)