| =============== |
| Hardening Modes |
| =============== |
| |
| .. contents:: |
| :local: |
| |
| .. _using-hardening-modes: |
| |
| Using hardening modes |
| ===================== |
| |
| The hardened mode enables a set of security-critical assertions that prevent |
| undefined behavior caused by violating preconditions of the standard library. |
| These assertions can be done with relatively little overhead in constant time |
| and are intended to be used in production. |
| |
| In addition to the hardened mode, libc++ also provides two other hardening |
| modes: |
| - safe mode; |
| - debug mode. |
| |
| The safe mode contains all the checks from the hardened mode and additionally |
| some checks for undefined behavior that incur relatively little overhead but |
| aren't security-critical. While the performance penalty is somewhat more |
| significant compared to the hardened mode, the safe mode is still intended to be |
| usable in production. |
| |
| The debug mode, in turn, contains all the checks from the safe mode and |
| additionally more expensive checks that may affect the complexity of algorithms. |
| The debug mode is intended to be used for testing, not in production. |
| |
| Vendors can set the default hardening mode by using the |
| ``LIBCXX_HARDENING_MODE`` variable at CMake configuration time. Setting |
| ``LIBCXX_HARDENING_MODE`` to ``hardened`` enables the hardened mode, and |
| similarly setting the variable to ``safe`` enables the safe mode, and to |
| ``debug`` enables the debug mode. The default value is ``unchecked`` which |
| doesn't enable any hardening. |
| |
| When hardening is enabled, the compiled library is built with the corresponding |
| mode enabled, **and** user code will be built with the same mode enabled by |
| default. If the mode is set to "unchecked" at the CMake configuration time, the |
| compiled library will not contain any assertions and the default when building |
| user code will be to have assertions disabled. As a user, you can consult your |
| vendor to know which level of hardening is enabled by default. |
| |
| Furthermore, independently of any vendor-selected default, users can always |
| control which level of hardening is enabled in their code by defining |
| ``_LIBCPP_ENABLE_HARDENED_MODE=0|1`` (or ``_LIBCPP_ENABLE_SAFE_MODE=0|1``, or |
| ``_LIBCPP_ENABLE_DEBUG_MODE=0|1``) before including any libc++ header (we |
| recommend passing ``-D_LIBCPP_ENABLE_HARDENED_MODE=X``, etc. to the compiler). |
| Note that if the compiled library was built by the vendor in the unchecked mode, |
| functions compiled inside the static or shared library won't have any hardening |
| enabled even if the user compiles with hardening enabled (the same is true for |
| the inverse case where the static or shared library was compiled **with** |
| hardening enabled but the user tries to disable it). However, most of the code |
| in libc++ is in the headers, so the user-selected value for |
| ``_LIBCPP_ENABLE_HARDENED|SAFE|DEBUG_MODE``, if any, will usually be respected. |
| |
| Enabling hardening has no impact on the ABI. |
| |
| Iterator bounds checking |
| ------------------------ |
| TODO(hardening) |