From: Justin Stitt <justinstitt@google.com>
When CONFIG_OVERFLOW_BEHAVIOR_TYPES=y, Clang 23+'s Overflow Behavior
Type[1] annotations are available (i.e. __ob_trap, __ob_wrap). When not
enabled, these need to be empty macros. Document the new annotation and
add links from sanitizer docs pointing to the arithmetic-overflow docs.
Link: https://clang.llvm.org/docs/OverflowBehaviorTypes.html [1]
Signed-off-by: Justin Stitt <justinstitt@google.com>
Co-developed-by: Kees Cook <kees@kernel.org>
Signed-off-by: Kees Cook <kees@kernel.org>
---
Cc: Marco Elver <elver@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Cc: Miguel Ojeda <ojeda@kernel.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: <kasan-dev@googlegroups.com>
Cc: <linux-doc@vger.kernel.org>
Cc: <llvm@lists.linux.dev>
---
Documentation/dev-tools/ubsan.rst | 13 +
Documentation/process/arithmetic-overflow.rst | 323 ++++++++++++++++++
Documentation/process/deprecated.rst | 39 +++
Documentation/process/index.rst | 1 +
include/linux/compiler_attributes.h | 12 +
MAINTAINERS | 1 +
6 files changed, 389 insertions(+)
create mode 100644 Documentation/process/arithmetic-overflow.rst
diff --git a/Documentation/dev-tools/ubsan.rst b/Documentation/dev-tools/ubsan.rst
index e3591f8e9d5b..9e0c0f048eef 100644
--- a/Documentation/dev-tools/ubsan.rst
+++ b/Documentation/dev-tools/ubsan.rst
@@ -71,6 +71,19 @@ unaligned accesses (CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y). One could
still enable it in config, just note that it will produce a lot of UBSAN
reports.
+Additional sanitizer options include::
+
+ CONFIG_OVERFLOW_BEHAVIOR_TYPES=y
+
+This enables checking for integer arithmetic wrap-around (overflow/underflow).
+It instruments signed and unsigned integer overflow, as well as implicit
+truncation operations. This option is currently limited to specific types
+via the ``__ob_trap`` and ``__ob_wrap`` annotations.
+
+For detailed information about arithmetic overflow handling, overflow behavior
+annotations, and best practices, see:
+Documentation/process/arithmetic-overflow.rst
+
References
----------
diff --git a/Documentation/process/arithmetic-overflow.rst b/Documentation/process/arithmetic-overflow.rst
new file mode 100644
index 000000000000..2f19990f189b
--- /dev/null
+++ b/Documentation/process/arithmetic-overflow.rst
@@ -0,0 +1,323 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _arithmetic_overflow:
+
+Arithmetic Overflow Resolutions for Linux
+=========================================
+
+Background
+----------
+
+When a calculation's result exceeds the involved storage ranges, several
+strategies can be followed to handle such an overflow (or underflow),
+including:
+
+ - Undefined (i.e. pretend it's impossible and the result depends on hardware)
+ - Wrap around (this is what 2s-complement representation does by default)
+ - Trap (create an exception so the problem can be handled in another way)
+ - Saturate (explicitly hold the maximum or minimum representable value)
+
+In the C standard, three basic types can be involved in arithmetic, and each
+has a default strategy for solving the overflow problem:
+
+ - Signed overflow is undefined
+ - Unsigned overflow explicitly wraps around
+ - Pointer overflow is undefined
+
+The Linux kernel uses ``-fno-strict-overflow`` which implies ``-fwrapv``
+and ``-fwrapv-pointer`` which treats signed integer overflow and pointer
+overflow respectively as being consistent with two's complement. This flag
+allows for consistency within the codebase about the expectations of
+overflowing arithmetic as well as prevents eager compiler optimizations.
+Note that :ref:`open-coded intentional arithmetic wrap-around is deprecated <open_coded_wrap_around>`.
+
+From here on, arithmetic overflow concerning signed, unsigned, or
+pointer types will be referred to as "wrap-around" since it is the
+default strategy for the kernel. There is no such thing as "undefined
+behavior" for arithmetic in Linux: it always wraps.
+
+Overflow Behavior Types
+-----------------------
+
+The newly available ``__ob_trap`` and ``__ob_wrap`` annotations provide
+fine-grained control over overflow behavior. These can be applied to
+integer types to unambiguously specify how arithmetic operations are
+expected to behave upon overflow. Currently, only Clang supports these
+annotations. The annotation defines two possible overflow behaviors:
+
+* ``wrap``: Ensures arithmetic operations wrap on overflow, providing
+ well-defined two's complement semantics according to the bitwidth of the
+ underlying type, regardless of any associated ``-fwrapv`` options or
+ sanitizers (integer overflow and truncation checks are suppressed)
+* ``trap``: Enables overflow and truncation checking for the type, even when
+ associated ``-fwrapv`` options are enabled. Without the sanitizer enabled
+ the compiler emits a trap instruction, otherwise the integer overflow
+ and truncation warnings are emitted but execution continues.
+
+Note that the sanitizer infrastructure is used for instrumentation shows
+up in logs as the "Undefined Behavior" sanitizer (UBSan), which may be
+confusing. Instead this should be thought of as the "Unexpected Behavior"
+sanitizer. Its infrastructure is used to report on unexpected wrapping
+behaviors: none of integer operations are "undefined" any more, as per
+the use of ``-fno-strict-overflow``, but instead UBSan will kick in when
+a type is explicitly marked as non-wrapping (i.e. trapping).
+
+
+Enablement
+~~~~~~~~~~
+
+When supported by the compiler, kernels can build with either
+``CONFIG_OVERFLOW_BEHAVIOR_TYPES_TRAP=y`` for trapping mode (i.e.
+mitigation enabled), or ``CONFIG_OVERFLOW_BEHAVIOR_TYPES_WARN=y`` which
+enables warn-only mode, which logs the overflows but will continue as
+if the type was not marked with ``__ob_trap``.
+
+Compiler Options
+^^^^^^^^^^^^^^^^
+
+Usage of the ``overflow_behavior`` attribute is gated behind the
+``-fexperimental-overflow-behavior-types`` compiler flag which
+is a ``-cc1`` flag, meaning the kernel passes it as ``-Xclang
+-fexperimental-overflow-behavior-types``.
+
+Sanitizer Case Lists
+^^^^^^^^^^^^^^^^^^^^
+
+Linux uses a Sanitizer Case List file to selectively enable certain
+sanitizers for specific types. Specifically, the overflow and truncation
+sanitizers have had their standard instrumentation disabled for all
+types. To "allowlist" specific types for instrumentation the kernel
+makes use of the in-source ``__ob_trap`` annotations to gain reporting
+by the sanitizers.
+
+Currently, type-based entries within a sanitizer case list are only
+supported by Clang. For more information on the syntax for SCL files
+refer to the Clang docs:
+https://clang.llvm.org/docs/SanitizerSpecialCaseList.html
+
+Syntax
+~~~~~~
+
+Creating Overflow Behavior Types is possible via two syntactic forms;
+
+**Attribute syntax:**
+
+.. code-block:: c
+
+ typedef unsigned int __attribute__((overflow_behavior(trap))) safe_uint;
+ typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint;
+
+**Keyword syntax:**
+
+.. code-block:: c
+
+ typedef unsigned int __ob_trap safe_uint;
+ typedef unsigned int __ob_wrap wrapping_uint;
+
+Both forms are semantically identical. The keyword syntax is shorter and can
+appear in the same positions as ``const`` or ``volatile``. The attribute syntax
+is more self-documenting, so Linux uses this form.
+
+When ``-fexperimental-overflow-behavior-types`` is not enabled, both the
+keywords (``__ob_wrap``, ``__ob_trap``) and the attribute are ignored with a
+warning.
+
+The feature can be queried with either
+``__has_extension(overflow_behavior_types)`` or
+``__has_attribute(overflow_behavior)``.
+
+Basic Usage
+^^^^^^^^^^^
+
+.. code-block:: c
+
+ typedef unsigned int __ob_wrap counter_t;
+ typedef unsigned long __ob_trap safe_size_type;
+
+ counter_t increment_counter(counter_t count) {
+ return count + 1;
+ }
+
+ safe_size_type calculate_buffer_size(safe_size_type base,
+ safe_size_type extra) {
+ return base + extra;
+ }
+
+In the first function, arithmetic on ``counter_t`` is well-defined
+wrapping. Its overflow will never be reported and unlike an plain
+``unsigned int`` its purpose is unambiguous: it is expected to wrap
+around. In the second function, arithmetic on ``safe_size_type`` is
+checked -- overflow will result in a trap or sanitizer report depending
+on the build configuration.
+
+Variables can be annotated directly:
+
+.. code-block:: c
+
+ void foo(int num) {
+ int __ob_trap a = num;
+ a += 42;
+
+ unsigned char __ob_wrap b = 255;
+ b += 10;
+ }
+
+
+Interaction with Compiler Options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Overflow behavior annotations override many global compiler flags and
+sanitizer configurations:
+
+* ``wrap`` types suppress UBSan's integer overflow checks
+ (``signed-integer-overflow``, ``unsigned-integer-overflow``) and implicit
+ truncation checks (``implicit-signed-integer-truncation``,
+ ``implicit-unsigned-integer-truncation``). They also suppress ``-ftrapv``
+ for the annotated type.
+* ``trap`` types enable overflow checking even when ``-fwrapv``
+ is globally enabled. When no sanitizer runtime is available, the compiler
+ emits a trap instruction directly.
+* Both forms override Sanitizer Special Case List (SSCL) entries.
+
+Common overflow idioms are excluded from instrumentation via
+``-fsanitize-undefined-ignore-overflow-pattern=``. These overflow idioms have
+their instrumentation withheld even under the presence of overflow behavior
+annotations. For more details see:
+https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#disabling-instrumentation-for-common-overflow-patterns
+
+Truncation Semantics
+^^^^^^^^^^^^^^^^^^^^
+
+Truncation and overflow are related -- both are often desirable in some
+contexts and undesirable in others. Overflow behavior types control truncation
+instrumentation at the type level as well:
+
+* If a ``trap`` type is involved as source or destination of a truncation, the
+ compiler inserts truncation checks. These will either trap or report via
+ sanitizer depending on the build configuration.
+* If a ``wrap`` type is involved as source or destination, truncation checks
+ are suppressed regardless of compiler flags.
+* If both ``trap`` and ``wrap`` are involved in the same truncation, ``wrap``
+ takes precedence (truncation checks are suppressed) since the explicit
+ wrapping intent covers truncation as well.
+
+.. code-block:: c
+
+ void checked(char a, int __ob_trap b) {
+ a = b;
+ }
+
+ void wrapping(char a, int __ob_wrap b) {
+ a = b;
+ }
+
+
+Promotion Rules
+^^^^^^^^^^^^^^^
+
+Overflow behavior types follow standard C integer promotion rules while
+preserving the overflow behavior annotation through expressions:
+
+* When an overflow behavior type is mixed with a standard integer type, the
+ result carries the overflow behavior annotation. Standard C conversion rules
+ determine the resulting width and signedness.
+* When two overflow behavior types of the same kind (both ``wrap`` or both
+ ``trap``) are mixed, the result follows standard C arithmetic conversion
+ rules with that behavior applied.
+* When ``wrap`` and ``trap`` are mixed, ``trap`` dominates. The result follows
+ standard C conversions with ``trap`` behavior.
+
+.. code-block:: c
+
+ typedef int __ob_wrap wrap_int;
+ typedef int __ob_trap trap_int;
+
+ wrap_int a = 1;
+ trap_int b = 2;
+ /* a + b results in __ob_trap int (trap dominates) */
+
+
+Type Compatibility
+^^^^^^^^^^^^^^^^^^
+
+Overflow behavior types are distinct from their underlying types for type
+checking purposes. Assigning between types with different overflow behaviors
+(``wrap`` vs ``trap``) is an error:
+
+.. code-block:: c
+
+ int __ob_wrap w;
+ int __ob_trap t;
+ w = t; /* error: incompatible overflow behavior types */
+
+Assigning from an overflow behavior type to a plain integer type discards the
+overflow behavior. The compiler can warn about this with
+``-Wimplicit-overflow-behavior-conversion`` (implied by ``-Wconversion``).
+
+Intentionally discarding the overflow behavior should use an explicit
+cast:
+
+.. code-block:: c
+
+ unsigned long __ob_trap checked_size;
+ unsigned long regular_size;
+
+ regular_size = checked_size; /* warning: discards overflow behavior */
+ regular_size = (unsigned long)checked_size; /* OK, explicit cast */
+
+If truncation should be allowed for a cast away from ``trap``, an
+explicit ``wrap`` cast is needed to suppress run-time instrumentation:
+
+.. code-block:: c
+
+ unsigned long __ob_trap checked_size;
+ unsigned char small_size;
+
+ small_size = checked_size; /* may trap at run-time on truncation */
+ small_size = (unsigned long __ob_wrap)checked_size; /* OK, explicit cast */
+
+
+Pointer Semantics
+^^^^^^^^^^^^^^^^^
+
+Pointers to overflow behavior types are treated as distinct from pointers to
+their underlying types. Converting between them produces a warning controlled
+by ``-Wincompatible-pointer-types-discards-overflow-behavior``:
+
+.. code-block:: c
+
+ unsigned long *px;
+ unsigned long __ob_trap *py;
+
+ px = py; /* warning: discards overflow behavior */
+ py = px; /* warning: discards overflow behavior */
+
+
+Best Practices
+^^^^^^^^^^^^^^
+
+1. **Use ``__ob_trap`` for sizes and counts** where overflow indicates bugs:
+
+ .. code-block:: c
+
+ typedef unsigned long long __ob_trap no_wrap_u64;
+ no_wrap_u64 buffer_len = kmalloc_size + header_size;
+
+2. **Use ``__ob_wrap`` for arithmetic that intentionally overflows**:
+
+ .. code-block:: c
+
+ typedef u32 __ob_wrap hash_t;
+ hash_t hash = (hash * 31) + byte;
+
+3. **Don't mix different overflow behavior types**:
+
+ .. code-block:: c
+
+ int __ob_wrap a;
+ int __ob_trap b;
+
+ a = b; /* error: incompatible overflow behavior types */
+
+ a = (int __ob_wrap)b; /* OK, explicit cast */
+ a = (int)b; /* OK, cast to underlying type */
diff --git a/Documentation/process/deprecated.rst b/Documentation/process/deprecated.rst
index fed56864d036..1c20f7ff0798 100644
--- a/Documentation/process/deprecated.rst
+++ b/Documentation/process/deprecated.rst
@@ -109,6 +109,45 @@ For more details, also see array3_size() and flex_array_size(),
as well as the related check_mul_overflow(), check_add_overflow(),
check_sub_overflow(), and check_shl_overflow() family of functions.
+.. _open_coded_wrap_around:
+
+open-coded intentional arithmetic wrap-around
+---------------------------------------------
+Depending on arithmetic wrap-around without annotations means the
+kernel cannot distinguish between intentional wrap-around and accidental
+wrap-around (when using things like the overflow sanitizers).
+
+For example, where an addition is intended to wrap around::
+
+ magic = counter + rotation;
+
+please use the wrapping_add() helper::
+
+ magic = wrapping_add(int, counter, rotation);
+
+To help minimize needless code churn, the kernel uses overflow idiom exclusions
+(currently only supported by Clang). Some commonly used overflow-dependent code
+patterns will not be instrumented by overflow sanitizers. The currently
+supported patterns are::
+
+ /* wrap-around test */
+ if (var + offset < var) ...
+
+ /* standalone unsigned decrement used in while loop */
+ while(size--)
+
+ /* negated unsigned constants */
+ -1UL;
+ -5U;
+
+In rare cases where helpers aren't available (e.g. in early boot code, etc) but
+overflow instrumentation still needs to be avoided, utilize wrap-around tests
+to check wrap-around outcomes before performing calculations::
+
+ if (var + offset < var) {
+ /* wrap-around has occurred */
+ }
+
simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
----------------------------------------------------------------------
The simple_strtol(), simple_strtoll(),
diff --git a/Documentation/process/index.rst b/Documentation/process/index.rst
index dbd6ea16aca7..620257eca00e 100644
--- a/Documentation/process/index.rst
+++ b/Documentation/process/index.rst
@@ -111,3 +111,4 @@ developers:
kernel-docs
deprecated
+ arithmetic-overflow
diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h
index c16d4199bf92..65f57ff378bb 100644
--- a/include/linux/compiler_attributes.h
+++ b/include/linux/compiler_attributes.h
@@ -396,6 +396,18 @@
# define __disable_sanitizer_instrumentation
#endif
+/*
+ * Optional: only supported by Clang with -Xclang -experimental-foverflow-behavior-types
+ * passed via CONFIG_OVERFLOW_BEHAVIOR_TYPES. When not available, define empty macros for
+ * the trap/wrap annotations.
+ *
+ * clang: https://clang.llvm.org/docs/OverflowBehaviorTypes.html
+ */
+#if !__has_attribute(overflow_behavior) || !defined(OVERFLOW_BEHAVIOR_TYPES)
+# define __ob_trap
+# define __ob_wrap
+#endif
+
/*
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-weak-function-attribute
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-weak-variable-attribute
diff --git a/MAINTAINERS b/MAINTAINERS
index a9f067164203..342a550c25b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19925,6 +19925,7 @@ M: Justin Stitt <justinstitt@google.com>
L: linux-hardening@vger.kernel.org
S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
+F: Documentation/process/arithmetic-overflow.rst
F: scripts/integer-wrap-ignore.scl
F: scripts/Makefile.obt
--
2.34.1
Hi Kees,
Many thanks for this series. Great work and I am ready it with a lot of
interest!
Le 31/03/2026 à 18:37, Kees Cook a écrit :
> From: Justin Stitt <justinstitt@google.com>
>
> When CONFIG_OVERFLOW_BEHAVIOR_TYPES=y, Clang 23+'s Overflow Behavior
> Type[1] annotations are available (i.e. __ob_trap, __ob_wrap). When not
> enabled, these need to be empty macros. Document the new annotation and
> add links from sanitizer docs pointing to the arithmetic-overflow docs.
>
> Link: https://clang.llvm.org/docs/OverflowBehaviorTypes.html [1]
> Signed-off-by: Justin Stitt <justinstitt@google.com>
> Co-developed-by: Kees Cook <kees@kernel.org>
> Signed-off-by: Kees Cook <kees@kernel.org>
> ---
> Cc: Marco Elver <elver@google.com>
> Cc: Andrey Konovalov <andreyknvl@gmail.com>
> Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
> Cc: Jonathan Corbet <corbet@lwn.net>
> Cc: Shuah Khan <skhan@linuxfoundation.org>
> Cc: Miguel Ojeda <ojeda@kernel.org>
> Cc: Nathan Chancellor <nathan@kernel.org>
> Cc: <kasan-dev@googlegroups.com>
> Cc: <linux-doc@vger.kernel.org>
> Cc: <llvm@lists.linux.dev>
> ---
> Documentation/dev-tools/ubsan.rst | 13 +
> Documentation/process/arithmetic-overflow.rst | 323 ++++++++++++++++++
> Documentation/process/deprecated.rst | 39 +++
> Documentation/process/index.rst | 1 +
> include/linux/compiler_attributes.h | 12 +
> MAINTAINERS | 1 +
> 6 files changed, 389 insertions(+)
> create mode 100644 Documentation/process/arithmetic-overflow.rst
>
> diff --git a/Documentation/dev-tools/ubsan.rst b/Documentation/dev-tools/ubsan.rst
> index e3591f8e9d5b..9e0c0f048eef 100644
> --- a/Documentation/dev-tools/ubsan.rst
> +++ b/Documentation/dev-tools/ubsan.rst
> @@ -71,6 +71,19 @@ unaligned accesses (CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y). One could
> still enable it in config, just note that it will produce a lot of UBSAN
> reports.
>
> +Additional sanitizer options include::
> +
> + CONFIG_OVERFLOW_BEHAVIOR_TYPES=y
> +
> +This enables checking for integer arithmetic wrap-around (overflow/underflow).
> +It instruments signed and unsigned integer overflow, as well as implicit
> +truncation operations. This option is currently limited to specific types
> +via the ``__ob_trap`` and ``__ob_wrap`` annotations.
> +
> +For detailed information about arithmetic overflow handling, overflow behavior
> +annotations, and best practices, see:
> +Documentation/process/arithmetic-overflow.rst
> +
> References
> ----------
>
> diff --git a/Documentation/process/arithmetic-overflow.rst b/Documentation/process/arithmetic-overflow.rst
> new file mode 100644
> index 000000000000..2f19990f189b
> --- /dev/null
> +++ b/Documentation/process/arithmetic-overflow.rst
> @@ -0,0 +1,323 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +.. _arithmetic_overflow:
> +
> +Arithmetic Overflow Resolutions for Linux
> +=========================================
> +
> +Background
> +----------
> +
> +When a calculation's result exceeds the involved storage ranges, several
> +strategies can be followed to handle such an overflow (or underflow),
> +including:
> +
> + - Undefined (i.e. pretend it's impossible and the result depends on hardware)
> + - Wrap around (this is what 2s-complement representation does by default)
> + - Trap (create an exception so the problem can be handled in another way)
> + - Saturate (explicitly hold the maximum or minimum representable value)
I just wanted to ask how much consideration was put into this last
"saturate" option.
When speaking of "safe" as in "functional safety" this seems a good
option to me. The best option is of course proper handling, but as
discussed, we are speaking of the scenario in which the code is already
buggy and which is the fallout option doing the least damage.
What I have in mind is a new __ob_saturate type qualifier. Something like:
void foo(int num)
{
int __ob_saturate saturate_var = num;
saturate_var += 42;
}
would just print a warning and continue execution, thus solving the
trapping issue. The above code would generate something equivalent to that:
void foo(int num)
{
int __ob_saturate saturate_var = num;
if (check_add_overflow(saturate_var, increment,
&saturate_var) {
WARN(true, "saturation occurred");
saturate_var = type_max(saturate_var);
}
People using those saturating integers could then later check that the
value is still in bound.
This is basically what your size_add() from overflow.h is already doing.
If an overflow occurred, the allocation the addition does not trap, it
just saturates and let the allocation functions properly handle the issue.
The saturation can neutralize many security attacks and can mitigate
some safety issues. Think of the Ariane 5 rocket launch: a saturation
could have prevented the unintended fireworks.
The caveat I can think of is that the old overflow check pattern becomes
invalid. Doing:
if (saturate_var + increment < increment)
is now bogus and would need to be caught if possible by static analysis.
So those saturating integers will only be usable in newly written code
and could not be easily retrofitted.
> +In the C standard, three basic types can be involved in arithmetic, and each
> +has a default strategy for solving the overflow problem:
> +
> + - Signed overflow is undefined
> + - Unsigned overflow explicitly wraps around
> + - Pointer overflow is undefined
Nitpick: the C standard uses different definitions than yours. In the
standard:
- overflow is *always* undefined
- unsigned integer wraparound
- signed integer overflow
The nuance is that in the standard unsigned integers do not overflow,
they just wraparound.
I am not asking you to change your terminology, but it could be good to
state in your document that your definition of overflow differs from the
standard's definition. Maybe a terminology section could help.
Yours sincerely,
Vincent Mailhol
On Tue, 31 Mar 2026 at 09:37, Kees Cook <kees@kernel.org> wrote:
>> +
> + typedef unsigned int __attribute__((overflow_behavior(trap))) safe_uint;
> + typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint;
This is fundamentally broken sh*t.
Stop thinking that trapping is "safe".
It damn well isn't. A dead machine is not a safe machine.
Any patches that call trapping behavior safe will ne NAK'ed by me.,
We have decades of peoiple using BUG_ON() as a safety measure, and it
has been a HUGE PROBLEM.
There is no way in hell that we are ever adding implicit BUG_ON()
things that are this hidden, this easy to use, and then mislabeled as
being "safe".
Guys, that's the same logic as having a airbag in your car that just
shoots you in the head. You're certainly "safe" from the vagaries of
bad healthcare. But dammit, if anybody thinks that a "bullet to the
head" should be called "safe", then that person damn well shouldn't be
involved with kernel development.
So NAK NAK NAK NAK.
The only safe trapping behavior is something that has a clear an
unambiguous and simple to use way to *HANDLE* it. Not just "mark it
trapping".
Linus
On Tue, 31 Mar 2026 at 10:16, Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> The only safe trapping behavior is something that has a clear an
> unambiguous and simple to use way to *HANDLE* it. Not just "mark it
> trapping".
Side note: this is the same kind of complete and utter idiocy that
made Rust people have allocators that abort when running out of
memory, because it's "safer" than returning NULL.
THAT KIND OF THINKING IS NOT ACCEPTABLE IN THE KERNEL.
I don't know why people keep doing this. Stop it.
Linus
On Tue, Mar 31, 2026 at 6:37 PM Kees Cook <kees@kernel.org> wrote:
>
> +/*
> + * Optional: only supported by Clang with -Xclang -experimental-foverflow-behavior-types
> + * passed via CONFIG_OVERFLOW_BEHAVIOR_TYPES. When not available, define empty macros for
> + * the trap/wrap annotations.
> + *
> + * clang: https://clang.llvm.org/docs/OverflowBehaviorTypes.html
> + */
> +#if !__has_attribute(overflow_behavior) || !defined(OVERFLOW_BEHAVIOR_TYPES)
> +# define __ob_trap
> +# define __ob_wrap
> +#endif
Should that have `CONFIG_*`? i.e.
!defined(CONFIG_OVERFLOW_BEHAVIOR_TYPES)
In addition, since this depends on a `CONFIG_`, with the current setup
we would put them elsewhere instead of `compiler_attributes.h` until
they are promoted to be "unconditional" (i.e. without the compiler
flag):
* Any other "attributes" (i.e. those that depend on a configuration option,
* on a compiler, on an architecture, on plugins, on other attributes...)
* should be defined elsewhere (e.g. compiler_types.h or compiler-*.h).
* The intention is to keep this file as simple as possible, as well as
* compiler- and version-agnostic (e.g. avoiding GCC_VERSION checks).
However, thinking about it, why is the config needed?
i.e. if the compiler is not passed that flag, shouldn't the
`__has_attribute` simply return false?
Also, I am a bit confused -- does the compiler flag automatically
recognize the names like `__ob_trap`? i.e. I see the docs mention
using the attribute,
typedef unsigned int __attribute__((overflow_behavior(trap))) safe_uint;
typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint;
But then we don't actually use it?
Or should this just be like the rest of the attributes, i.e. we
actually define them here?
Thanks!
Cheers,
Miguel
On Tue, Mar 31, 2026 at 7:01 PM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> Also, I am a bit confused -- does the compiler flag automatically
> recognize the names like `__ob_trap`? i.e. I see the docs mention
> using the attribute,
>
> typedef unsigned int __attribute__((overflow_behavior(trap))) safe_uint;
> typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint;
>
> But then we don't actually use it?
Ah, it does, it is a keyword, and I should have read the docs better.
From a quick test in Compiler Explorer it seems to be fine to define a
macro like the keyword:
#define __ob_trap __attribute__((overflow_behavior(trap)))
#define __ob_wrap __attribute__((overflow_behavior(wrap)))
That could be a bit more flexible in the name we pick on our side and
more like the rest of the attributes, but if the intention is to
eventually use that keyword in standard C or similar, I guess it is
fine.
Cheers,
Miguel
Hi, On Tue, Mar 31, 2026 at 10:02 AM Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote: > > On Tue, Mar 31, 2026 at 6:37 PM Kees Cook <kees@kernel.org> wrote: > > > > +/* > > + * Optional: only supported by Clang with -Xclang -experimental-foverflow-behavior-types > > + * passed via CONFIG_OVERFLOW_BEHAVIOR_TYPES. When not available, define empty macros for > > + * the trap/wrap annotations. > > + * > > + * clang: https://clang.llvm.org/docs/OverflowBehaviorTypes.html > > + */ > > +#if !__has_attribute(overflow_behavior) || !defined(OVERFLOW_BEHAVIOR_TYPES) > > +# define __ob_trap > > +# define __ob_wrap > > +#endif > > Should that have `CONFIG_*`? i.e. > > !defined(CONFIG_OVERFLOW_BEHAVIOR_TYPES) > > In addition, since this depends on a `CONFIG_`, with the current setup > we would put them elsewhere instead of `compiler_attributes.h` until > they are promoted to be "unconditional" (i.e. without the compiler > flag): > > * Any other "attributes" (i.e. those that depend on a configuration option, > * on a compiler, on an architecture, on plugins, on other attributes...) > * should be defined elsewhere (e.g. compiler_types.h or compiler-*.h). > * The intention is to keep this file as simple as possible, as well as > * compiler- and version-agnostic (e.g. avoiding GCC_VERSION checks). > > However, thinking about it, why is the config needed? > > i.e. if the compiler is not passed that flag, shouldn't the > `__has_attribute` simply return false? > > Also, I am a bit confused -- does the compiler flag automatically > recognize the names like `__ob_trap`? i.e. I see the docs mention > using the attribute, > > typedef unsigned int __attribute__((overflow_behavior(trap))) safe_uint; > typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint; > > But then we don't actually use it? __ob_trap and __ob_wrap are defined by the compiler. There are some examples within the documentation additions of this patch. Kees, is it possible to make it more clear about what we expect of kernel developers in terms of style? Should they use keyword spellings? attribute spellings? only use custom types? > > Or should this just be like the rest of the attributes, i.e. we > actually define them here? > > Thanks! > > Cheers, > Miguel Justin
On Tue, Mar 31, 2026 at 10:09:33AM -0700, Justin Stitt wrote: > Hi, > > On Tue, Mar 31, 2026 at 10:02 AM Miguel Ojeda > <miguel.ojeda.sandonis@gmail.com> wrote: > > > > On Tue, Mar 31, 2026 at 6:37 PM Kees Cook <kees@kernel.org> wrote: > > > > > > +/* > > > + * Optional: only supported by Clang with -Xclang -experimental-foverflow-behavior-types > > > + * passed via CONFIG_OVERFLOW_BEHAVIOR_TYPES. When not available, define empty macros for > > > + * the trap/wrap annotations. > > > + * > > > + * clang: https://clang.llvm.org/docs/OverflowBehaviorTypes.html > > > + */ > > > +#if !__has_attribute(overflow_behavior) || !defined(OVERFLOW_BEHAVIOR_TYPES) > > > +# define __ob_trap > > > +# define __ob_wrap > > > +#endif > > > > Should that have `CONFIG_*`? i.e. > > > > !defined(CONFIG_OVERFLOW_BEHAVIOR_TYPES) > > > > In addition, since this depends on a `CONFIG_`, with the current setup > > we would put them elsewhere instead of `compiler_attributes.h` until > > they are promoted to be "unconditional" (i.e. without the compiler > > flag): > > > > * Any other "attributes" (i.e. those that depend on a configuration option, > > * on a compiler, on an architecture, on plugins, on other attributes...) > > * should be defined elsewhere (e.g. compiler_types.h or compiler-*.h). > > * The intention is to keep this file as simple as possible, as well as > > * compiler- and version-agnostic (e.g. avoiding GCC_VERSION checks). > > > > However, thinking about it, why is the config needed? > > > > i.e. if the compiler is not passed that flag, shouldn't the > > `__has_attribute` simply return false? > > > > Also, I am a bit confused -- does the compiler flag automatically > > recognize the names like `__ob_trap`? i.e. I see the docs mention > > using the attribute, > > > > typedef unsigned int __attribute__((overflow_behavior(trap))) safe_uint; > > typedef unsigned int __attribute__((overflow_behavior(wrap))) wrapping_uint; > > > > But then we don't actually use it? > > __ob_trap and __ob_wrap are defined by the compiler. > > There are some examples within the documentation additions of this patch. > > Kees, is it possible to make it more clear about what we expect of > kernel developers in terms of style? Should they use keyword > spellings? attribute spellings? only use custom types? I think for this series, __ob_trap/__ob_wrap is what should be used. And for other folks, the background here is that we originally wanted to use macros for "__trap" and "__wrap", but the powerpc C compiler (both Clang and GCC) have a builtin macro named "__trap" already. So I switched to just using the Clang-native type qualifier. We can use the attribute style too, but there was a lot of confusion during the Clang development phases where people kept forgetting this was a type qualifier, not an attribute (i.e. the attribute is an internal alias for the qualifier, and the qualifier is a new type). -- Kees Cook
On Tue, Mar 31, 2026 at 7:09 PM Justin Stitt <justinstitt@google.com> wrote: > > __ob_trap and __ob_wrap are defined by the compiler. > > There are some examples within the documentation additions of this patch. > > Kees, is it possible to make it more clear about what we expect of > kernel developers in terms of style? Should they use keyword > spellings? attribute spellings? only use custom types? Yeah, I noticed that right after sending the email, sorry. So I tried to use a macro even if happens to have the same name as the keyword, since that form is a bit more flexible, but it is fine either way. What I would suggest is adding to the comment that these were decided to be used as keywords, and thus we only need to define them as empty in the disabled case. Thanks! Cheers, Miguel
Hi, On Tue, Mar 31, 2026 at 10:14 AM Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> wrote: > > On Tue, Mar 31, 2026 at 7:09 PM Justin Stitt <justinstitt@google.com> wrote: > > > > __ob_trap and __ob_wrap are defined by the compiler. > > > > There are some examples within the documentation additions of this patch. > > > > Kees, is it possible to make it more clear about what we expect of > > kernel developers in terms of style? Should they use keyword > > spellings? attribute spellings? only use custom types? > > Yeah, I noticed that right after sending the email, sorry. > > So I tried to use a macro even if happens to have the same name as the > keyword, since that form is a bit more flexible, but it is fine either > way. > > What I would suggest is adding to the comment that these were decided > to be used as keywords, and thus we only need to define them as empty > in the disabled case. Agreed. > > Thanks! > > Cheers, > Miguel Justin
© 2016 - 2026 Red Hat, Inc.