[libcxx-commits] [libcxx] [libcxx] reorganises the hardening documentation (PR #73159)

Christopher Di Bella via libcxx-commits libcxx-commits at lists.llvm.org
Tue Dec 5 14:38:28 PST 2023


https://github.com/cjdb updated https://github.com/llvm/llvm-project/pull/73159

>From 1637fdc420fdcc4c0903960e537ff5504b389890 Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Wed, 22 Nov 2023 18:37:09 +0000
Subject: [PATCH 1/6] [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.
---
 libcxx/docs/Hardening.rst | 118 +++++++++++++++++++++-----------------
 1 file changed, 64 insertions(+), 54 deletions(-)

diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst
index 7692f2a2c7887..2cc0f557c2736 100644
--- a/libcxx/docs/Hardening.rst
+++ b/libcxx/docs/Hardening.rst
@@ -15,61 +15,71 @@ assertions that prevent undefined behavior caused by violating preconditions of
 the standard library. Different hardening modes make different trade-offs
 between the amount of checking and runtime performance. The available hardening
 modes are:
-- fast mode;
-- extensive mode;
-- debug mode.
-
-The fast mode contains a set of security-critical checks that can be done with
-relatively little overhead in constant time and are intended to be used in
-production. We recommend most projects to adopt the fast mode.
-
-The extensive mode contains all the checks from the fast 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 fast mode, the extensive mode is still intended to
-be usable in production.
-
-The debug mode enables all the available checks in the library, including
-internal assertions, some of which might be very expensive. This 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 with the possible
-values of ``none``, ``fast``, ``extensive`` and ``debug``. The default value is
-``none`` which doesn't enable any hardening checks (this mode is sometimes
-called the ``unchecked`` mode).
-
-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 "none" 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 the macro
-``_LIBCPP_HARDENING_MODE`` before including any libc++ headers (preferably by
-passing ``-D_LIBCPP_HARDENING_MODE=X`` to the compiler). The macro can be
-set to one of the following possible values:
-
-- ``_LIBCPP_HARDENING_MODE_NONE``;
-- ``_LIBCPP_HARDENING_MODE_FAST``;
-- ``_LIBCPP_HARDENING_MODE_EXTENSIVE``;
-- ``_LIBCPP_HARDENING_MODE_DEBUG``.
-
-The exact numeric values of these macros are unspecified and users should not
-rely on them (e.g. expect the values to be sorted in any way).
-
-Note that if the compiled library was built by the vendor with the hardening
-mode set to "none", 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_HARDENING_MODE``, if any, will usually be respected.
-
-Enabling hardening has no impact on the ABI.
+
+- **Unchecked mode/none**, which disables all hardening checks.
+- **Fast mode**, which contains a set of security-critical checks that can be
+  done with relatively little overhead in constant time and are intended to be
+  used in production. We recommend most projects to adopt the fast mode.
+- **Extensive mode**, which contains all the checks from the fast 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 fast mode, the extensive mode is
+  still intended to be usable in production.
+- **Debug mode**, which enables all the available checks in the library,
+  including internal assertions, some of which might be very expensive. This
+  mode is intended to be used for testing, not in production.
+
+.. note::
+
+   Enabling hardening has no impact on the ABI.
+
+Notes for users
+---------------
+
+As a user, you can consult your vendor to know which level of hardening is
+enabled by default.
+
+Users wishing for a different hardening level to their vendor default are able
+to control the level by passing **one** of the following options to the compiler:
+
+- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_NONE``
+- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST``
+- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE``
+- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_DEBUG``
+
+.. warning::
+
+   The exact numeric values of these macros are unspecified and users should not
+   rely on them (e.g. expect the values to be sorted in any way).
+
+.. warning::
+
+   If you would prefer to override the hardening level on a per-translation-unit
+   basis, you must do so **before** including any headers to avoid `ODR issues`_.
+
+.. _`ODR issues`: https://en.cppreference.com/w/cpp/language/definition#:~:text=is%20ill%2Dformed.-,One%20Definition%20Rule,-Only%20one%20definition
+
+.. note::
+
+   Since the static and shared library components of libc++ are built by the
+   vendor, setting this macro will have no impact on the hardening mode for the
+   pre-built components. Most libc++ code is header-based, so a user-provided
+   value for ``_LIBCPP_HARDENING_MODE`` will be mostly respected.
+
+Notes for vendors
+-----------------
+
+Vendors can set the default hardening mode by providing ``LIBCXX_HARDENING_MODE``
+as a configuration option, with the possible values of ``none``, ``fast``,
+``extensive`` and ``debug``. The default value is ``none`` which doesn't enable
+any hardening checks (this mode is sometimes called the ``unchecked`` mode).
+
+This option controls both the hardening mode that the precompiled library is
+built with and the default hardening mode that users will build with. If set to
+``none``, the precompiled library will not contain any assertions, and user code
+will default to building without assertions.
 
 Iterator bounds checking
 ------------------------
+
 TODO(hardening)

>From 3964324af413ac057a68d5dbeafda67e43879a91 Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb.ns at gmail.com>
Date: Wed, 22 Nov 2023 14:52:52 -0800
Subject: [PATCH 2/6] Update libcxx/docs/Hardening.rst

Co-authored-by: Will Hawkins <whh8b at obs.cr>
---
 libcxx/docs/Hardening.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst
index 2cc0f557c2736..8bdbe249c6ab2 100644
--- a/libcxx/docs/Hardening.rst
+++ b/libcxx/docs/Hardening.rst
@@ -36,7 +36,7 @@ modes are:
 Notes for users
 ---------------
 
-As a user, you can consult your vendor to know which level of hardening is
+As a libc++ user, consult with your vendor to determine the level of hardening
 enabled by default.
 
 Users wishing for a different hardening level to their vendor default are able

>From 6bc17e4a491379e34931031bb508efead1be1f30 Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb.ns at gmail.com>
Date: Wed, 22 Nov 2023 14:53:47 -0800
Subject: [PATCH 3/6] Update libcxx/docs/Hardening.rst

Co-authored-by: Will Hawkins <whh8b at obs.cr>
---
 libcxx/docs/Hardening.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst
index 8bdbe249c6ab2..04b2d3745ea55 100644
--- a/libcxx/docs/Hardening.rst
+++ b/libcxx/docs/Hardening.rst
@@ -24,7 +24,7 @@ modes are:
   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 fast mode, the extensive mode is
-  still intended to be usable in production.
+  still intended for use in production builds.
 - **Debug mode**, which enables all the available checks in the library,
   including internal assertions, some of which might be very expensive. This
   mode is intended to be used for testing, not in production.

>From b7b302c4e2bc06474af75b54a0c2f8c6c9c88428 Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb.ns at gmail.com>
Date: Wed, 22 Nov 2023 14:55:07 -0800
Subject: [PATCH 4/6] Update libcxx/docs/Hardening.rst

Co-authored-by: Will Hawkins <whh8b at obs.cr>
---
 libcxx/docs/Hardening.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst
index 04b2d3745ea55..9a903c8346cdc 100644
--- a/libcxx/docs/Hardening.rst
+++ b/libcxx/docs/Hardening.rst
@@ -21,7 +21,7 @@ modes are:
   done with relatively little overhead in constant time and are intended to be
   used in production. We recommend most projects to adopt the fast mode.
 - **Extensive mode**, which contains all the checks from the fast mode and
-  additionally some checks for undefined behavior that incur relatively little
+  some additional 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 fast mode, the extensive mode is
   still intended for use in production builds.

>From deeb372fbfb3236f17a8af8eb906d7d55ee3dde3 Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Tue, 5 Dec 2023 21:52:09 +0000
Subject: [PATCH 5/6] adjusts extensive mode description

---
 libcxx/docs/Hardening.rst | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst
index 9a903c8346cdc..d9de4e242788e 100644
--- a/libcxx/docs/Hardening.rst
+++ b/libcxx/docs/Hardening.rst
@@ -22,9 +22,10 @@ modes are:
   used in production. We recommend most projects to adopt the fast mode.
 - **Extensive mode**, which contains all the checks from the fast mode and
   some additional 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 fast mode, the extensive mode is
-  still intended for use in production builds.
+  overhead but aren't security-critical. Production builds requiring a broader
+  set of checks than fast mode should consider enabling extensive mode. The
+  additional rigour impacts performance more than fast mode: we recommend
+  benchmarking to determine if that is acceptable for your program.
 - **Debug mode**, which enables all the available checks in the library,
   including internal assertions, some of which might be very expensive. This
   mode is intended to be used for testing, not in production.

>From f368cafa699ca9b32acdf3d8eff8446f3bb869fd Mon Sep 17 00:00:00 2001
From: Christopher Di Bella <cjdb at google.com>
Date: Tue, 5 Dec 2023 21:59:16 +0000
Subject: [PATCH 6/6] a few more tweaks

---
 libcxx/docs/Hardening.rst | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/libcxx/docs/Hardening.rst b/libcxx/docs/Hardening.rst
index d9de4e242788e..33a168d6e1683 100644
--- a/libcxx/docs/Hardening.rst
+++ b/libcxx/docs/Hardening.rst
@@ -19,13 +19,13 @@ modes are:
 - **Unchecked mode/none**, which disables all hardening checks.
 - **Fast mode**, which contains a set of security-critical checks that can be
   done with relatively little overhead in constant time and are intended to be
-  used in production. We recommend most projects to adopt the fast mode.
-- **Extensive mode**, which contains all the checks from the fast mode and
-  some additional checks for undefined behavior that incur relatively little
-  overhead but aren't security-critical. Production builds requiring a broader
-  set of checks than fast mode should consider enabling extensive mode. The
-  additional rigour impacts performance more than fast mode: we recommend
-  benchmarking to determine if that is acceptable for your program.
+  used in production. We recommend most projects adopt this.
+- **Extensive mode**, which contains all the checks from fast mode and some
+  additional checks for undefined behavior that incur relatively little overhead
+  but aren't security-critical. Production builds requiring a broader set of
+  checks than fast mode should consider enabling extensive mode. The additional
+  rigour impacts performance more than fast mode: we recommend benchmarking to
+  determine if that is acceptable for your program.
 - **Debug mode**, which enables all the available checks in the library,
   including internal assertions, some of which might be very expensive. This
   mode is intended to be used for testing, not in production.



More information about the libcxx-commits mailing list