Skip to content

Commit 1637fdc

Browse files
committed
[libcxx] reorganises the hardening documentation
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.
1 parent d6fbd96 commit 1637fdc

File tree

1 file changed

+64
-54
lines changed

1 file changed

+64
-54
lines changed

libcxx/docs/Hardening.rst

Lines changed: 64 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,61 +15,71 @@ 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 to adopt the fast mode.
23+
- **Extensive mode**, which contains all the checks from the fast mode and
24+
additionally some checks for undefined behavior that incur relatively little
25+
overhead but aren't security-critical. While the performance penalty is
26+
somewhat more significant compared to the fast mode, the extensive mode is
27+
still intended to be usable in production.
28+
- **Debug mode**, which enables all the available checks in the library,
29+
including internal assertions, some of which might be very expensive. This
30+
mode is intended to be used for testing, not in production.
31+
32+
.. note::
33+
34+
Enabling hardening has no impact on the ABI.
35+
36+
Notes for users
37+
---------------
38+
39+
As a user, you can consult your vendor to know which level of hardening is
40+
enabled by default.
41+
42+
Users wishing for a different hardening level to their vendor default are able
43+
to control the level by passing **one** of the following options to the compiler:
44+
45+
- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE``
46+
- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST``
47+
- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE``
48+
- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG``
49+
50+
.. warning::
51+
52+
The exact numeric values of these macros are unspecified and users should not
53+
rely on them (e.g. expect the values to be sorted in any way).
54+
55+
.. warning::
56+
57+
If you would prefer to override the hardening level on a per-translation-unit
58+
basis, you must do so **before** including any headers to avoid `ODR issues`_.
59+
60+
.. _`ODR issues`: https://en.cppreference.com/w/cpp/language/definition#:~:text=is%20ill%2Dformed.-,One%20Definition%20Rule,-Only%20one%20definition
61+
62+
.. note::
63+
64+
Since the static and shared library components of libc++ are built by the
65+
vendor, setting this macro will have no impact on the hardening mode for the
66+
pre-built components. Most libc++ code is header-based, so a user-provided
67+
value for ``_LIBCPP_HARDENING_MODE`` will be mostly respected.
68+
69+
Notes for vendors
70+
-----------------
71+
72+
Vendors can set the default hardening mode by providing ``LIBCXX_HARDENING_MODE``
73+
as a configuration option, with the possible values of ``none``, ``fast``,
74+
``extensive`` and ``debug``. The default value is ``none`` which doesn't enable
75+
any hardening checks (this mode is sometimes called the ``unchecked`` mode).
76+
77+
This option controls both the hardening mode that the precompiled library is
78+
built with and the default hardening mode that users will build with. If set to
79+
``none``, the precompiled library will not contain any assertions, and user code
80+
will default to building without assertions.
7281

7382
Iterator bounds checking
7483
------------------------
84+
7585
TODO(hardening)

0 commit comments

Comments
 (0)