Skip to content

Commit 6809933

Browse files
committed
Improve -fno-strict-overflow description
Add -ftrapv and -fsanitize=signed-integer-overflow as alternative option Signed-off-by: Thomas Nyman <[email protected]>
1 parent d0b03a3 commit 6809933

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

docs/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ Table 2: Recommended compiler options that enable run-time protection mechanisms
222222
| [`-fPIE -pie`](#-fPIE_-pie) | Binutils 2.16.0<br/>Clang 5.0.0 | Build as position-independent executable. Can impact performance on 32-bit architectures. |
223223
| [`-fPIC -shared`](#-fPIC_-shared) | < Binutils 2.6.0<br/>Clang 5.0.0 | Build as position-independent code. Can impact performance on 32-bit architectures. |
224224
| [`-fno-delete-null-pointer-checks`](#-fno-delete-null-pointer-checks) | GCC 3.0.0<br/>Clang 7.0.0 | Force retention of null pointer checks |
225-
| [`-fno-strict-overflow`](#-fno-strict-overflow) | GCC 4.2.0 | Integer overflow may occur |
225+
| [`-fno-strict-overflow`](#-fno-strict-overflow) | GCC 4.2.0 | Define behavior for signed integer and pointer arithmetic overflows |
226226
| [`-fno-strict-aliasing`](#-fno-strict-aliasing) | GCC 2.95.3<br/>Clang 2.9.0 | Do not assume strict aliasing |
227227
| [`-ftrivial-auto-var-init`](#-ftrivial-auto-var-init) | GCC 12.0.0<br/>Clang 8.0.0 | Perform trivial auto variable initialization |
228228
| [`-fexceptions`](#-fexceptions) | GCC 2.95.3<br/>Clang 2.6.0 | Enable exception propagation to harden multi-threaded C code |
@@ -947,15 +947,18 @@ There are normally no significant performance implications. Null pointer checks
947947
948948
---
949949
950-
### Integer overflow may occur
950+
### Define behavior for signed integer and pointer arithmetic overflows
951951
952-
| Compiler Flag | Supported since | Description |
953-
|:------------------------------------------------------------- |:---------------:|:----------------------------------------------------------------- |
954-
| <span id="-fno-strict-overflow">`-fno-strict-overflow`</span> | GCC 4.2.0 | Integer overflow may occur |
952+
| Compiler Flag | Supported since | Description |
953+
|:------------------------------------------------------------- |:---------------:|:---------------------------------------------------------------------------------------------------------------------------------------------- |
954+
| <span id="-fno-strict-overflow">`-fno-strict-overflow`</span> | GCC 8.5.0 | Signed integer overflows on addition, subtraction, multiplication, and pointer arithmetic wraps around using two's-completment representation |
955+
| <span id="-fwrapv">`-fwrapv`</span> | GCC 3.4.0 | Signed integer overflows on addition, subtraction, and multiplication wraps around using twos-completment representation |
956+
| <span id="-fwrapv-pointer">`-fwrapv-pointer`</span> | GCC 8.5.0 | Pointer arithmetic and multiplication wraps around using two's-complement representation |
957+
| <span id="-ftrapv">`-ftrapv`</span> | GCC 3.3.0 | Signed integer overflows on addition, subtraction and multiplication trap with `SIGABRT` |
955958
956959
#### Synopsis
957960
958-
In C and C++ unsigned integers have long been defined as "wrapping around". However, for many years C and C++ have assumed that overflows do not occur in many other circumstances. Overflow when doing arithmetic with signed numbers is considered undefined by many versions of the official specifications, This approach also allows the compiler to assume strict pointer semantics: if adding an offset to a pointer does not produce a pointer to the same object. In practice, this means that important security checks written in the source code may be silently ignored when generating executable code.
961+
In C and C++ unsigned integers have long been defined as "wrapping around". However, C and C++ compilers, by default, assume that overflows do not occur in other circumstances. Overflow when doing arithmetic with signed numbers is considered undefined in the language specifications. This allows the compiler to assume strict pointer semantics: if adding an offset to a pointer does not produce a pointer to the same object, the addition is undefined. In practice, this means that important security checks written in the source code may be silently ignored when generating executable code.
959962
960963
For example, here is some code from `fs/open.c` of the Linux kernel [^Wang2012]:
961964
@@ -977,9 +980,9 @@ A developer *might* expect that the computation `offset + len` would produce a u
977980

978981
The Linux kernel enables `-no-strict-overflow` to reduce the likelihood that important security checks in the source code will be silently ignored by the compiler.
979982

980-
An alternative option is to use the `-fwrapv` option. With `-fwrapv`, integer signed overflow wraps (and is thus defined).
983+
Alternatives to `-no-strict-overflow` are the `-fwrapv` and `-ftrapv` options. With `-fwrapv`, integer signed overflow wraps (and is thus defined). With `-ftrapv`, signed integer overflows trap, e.g., on x86 an overflow causes a `SIGABRT` signal to the application.
981984

982-
Note that GCC and Clang interpret this option slightly differently. On clang, this option is considered a synonym for `-fwrapv`. On GCC, this option does not fully enforce two's complement on signed integers, allowing for additional optimizations. [^Wang2012]
985+
Since GCC 8.5 `-no-strict-overflow` is equivalent to `-fwrapv -fwrapv-pointer` while GCC documentation recommends `-fsanitize=signed-integer-overflow` for diagnosing signed integer overflow issues during testing and debugging. In prior GCC versions `-no-strict-overflow` does not fully enforce two's complement on signed integers, allowing for additional optimizations[^Wang2012]. In Clang, `-no-strict-overflow` option is considered a synonym for `-fwrapv`.
983986

984987
---
985988

0 commit comments

Comments
 (0)