Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -494,11 +494,11 @@ Some tools, such as `autoconf`, automatically determine what the compiler suppor

### Fortify sources for unsafe libc usage and buffer overflows

| Compiler Flag | Supported since | Description |
| ------------------------------------------------------------------------------------------ | ----------------------- | -------------------------------------------------------------------------------------------- |
| <span id="-D_FORTIFY_SOURCE=1">`-D_FORTIFY_SOURCE=1`</span> | GCC 4.0.0<br/>Clang 5.0.0 | Fortify sources with compile- and run-time checks for unsafe libc usage and buffer overflows |
| <span id="-D_FORTIFY_SOURCE=2">`-D_FORTIFY_SOURCE=2`</span><br/>(requires `-O1` or higher) | GCC 4.0.0<br/>Clang 5.0.0[^Guelton20] | In addition to checks covered by `-D_FORTIFY_SOURCE=1`, also trap code that may be conforming to the C standard but still unsafe |
| <span id="-D_FORTIFY_SOURCE=3">`-D_FORTIFY_SOURCE=3`</span><br/>(requires `-O1` or higher) | GCC 12.0.0<br/>Clang 9.0.0[^Guelton20] | Same checks as in `-D_FORTIFY_SOURCE=2`, but with significantly more calls fortified with a potential to impact performance in some rare cases |
| Compiler Flag | Supported since | Description |
| ----------------------------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <span id="-D_FORTIFY_SOURCE=3">`-D_FORTIFY_SOURCE=3`</span> | GCC 12.0.0<br/>Clang 9.0.0[^Guelton20] | Same checks as in `-D_FORTIFY_SOURCE=2`, but with significantly more calls fortified with a potential to impact performance in some rare cases. Requires `-O1` or higher. |
| <span id="-D_FORTIFY_SOURCE=2">`-D_FORTIFY_SOURCE=2`</span> | GCC 4.0.0<br/>Clang 5.0.0[^Guelton20] | In addition to checks covered by `-D_FORTIFY_SOURCE=1`, also trap code that may be conforming to the C standard but still unsafe. Requires `-O1` or higher. |
| <span id="-D_FORTIFY_SOURCE=1">`-D_FORTIFY_SOURCE=1`</span> | GCC 4.0.0<br/>Clang 5.0.0 | Fortify sources with compile- and run-time checks for unsafe libc usage and buffer overflows |

#### Synopsis

Expand Down Expand Up @@ -535,14 +535,20 @@ Both `_FORTIFY_SOURCE=1` and `_FORTIFY_SOURCE=2` are expected to have a negligib

#### Additional Considerations

- Applications that incorrectly use `malloc_usable_size`[^malloc_usable_size] to use the additional size reported by the function may abort at runtime. This is a bug in the application because the additional size reported by `malloc_usable_size` is not generally safe to dereference and is for diagnostic uses only. The correct fix for such issues is to avoid using `malloc_usable_size` as the glibc manual specifically states that it is for diagnostic purposes *only* [^malloc_usable_size]. On many Linux systems these incorrect uses can be detected by running `readelf -Ws <path>` on the ELF binaries and searching for `malloc_usable_size@GLIBC`[^kpyrd23]. If avoiding `malloc_usable_size` is not possible, one may call `realloc` to resize the block to its usable size and to benefit from `_FORTIFY_SOURCE=3`.
Internally `-D_FORTIFY_SOURCE` relies on the built-in functions for object size checking in GCC[^gcc-objectsizechecks] and Clang[^clang-evaluatingobjectsize], namely `__builtin_object_size` and `__builtin_dynamic_object_size`. These builtins provide conservative approximations of the object size and are sensitive to compiler optimizations. With optimization enabled they produce more accurate estimates, especially when a call to `__builtin_object_size` is in a different function from where its argument pointer is formed. In addition, GCC allows more information about subobject bounds to be determined with higher optimization levels. Hence we recommending enabling `-D_FORTIFY_SOURCE=3` with at least optimization level `-O2`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't call out the subobject bounds so prominently because in practice better optimization can also sometimes result in subobject information being lost. I think a more reliable claim would be that higher optimization allows more number of __builtin_object_size and __builtin_dynamic_object_size calls to succeed, not the accuracy of their size estimates.


Applications that incorrectly use `malloc_usable_size`[^malloc_usable_size] to use the additional size reported by the function may abort at runtime. This is a bug in the application because the additional size reported by `malloc_usable_size` is not generally safe to dereference and is for diagnostic uses only. The correct fix for such issues is to avoid using `malloc_usable_size` as the glibc manual specifically states that it is for diagnostic purposes *only* [^malloc_usable_size]. On many Linux systems these incorrect uses can be detected by running `readelf -Ws <path>` on the ELF binaries and searching for `malloc_usable_size@GLIBC`[^kpyrd23]. If avoiding `malloc_usable_size` is not possible, one may call `realloc` to resize the block to its usable size and to benefit from `_FORTIFY_SOURCE=3`.
Copy link
Contributor

@siddhesh siddhesh Sep 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

systemd for example uses a dummy realloc hack to fool the compiler into thinking that the larger block is available, but I don't know if it's a good idea to recommend such practice:

https://github.com/systemd/systemd/blob/main/src/basic/alloc-util.h#L192

Also, I had introduced a fast path in realloc in glibc-2.37 that makes such hacks unnecessary since the glibc realloc should return the same block immediately if the new size fits into it. That may or may not be true for alternate allocators though.

Copy link
Contributor

@thesamesam thesamesam Sep 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're in the business of telling people what best practice is, we should indeed actively tell them not to do that at all. The only reason we haven't completely killed it in glibc is because we can't quite agree on how to move forward, but everyone accepts that using it like this is bad.

(I haven't brought it up again given that I haven't hit any other instances.)


[^glibc-fortification]: GNU C Library team, [Source Fortification in the GNU C Library](https://www.gnu.org/software/libc/manual/html_node/Source-Fortification.html), GNU C Library (glibc) manual, 2023-02-01.

[^Poyarekar23]: Poyarekar, Siddhesh, [How to improve application security using _FORTIFY_SOURCE=3](https://developers.redhat.com/articles/2023/02/06/how-improve-application-security-using-fortifysource3), Red Hat Developer, 2023-02-06.

[^gcc-zerolengtharrays]: GCC team, [Arrays of Length Zero](https://gcc.gnu.org/onlinedocs/gcc/extensions-to-the-c-language-family/arrays-of-length-zero.html), GCC Manual (experimental 20221114 documentation), 2022-11-14.

[^gcc-objectsizechecks]: GCC team, [Using the GNU Compiler Collection (GCC): 6.62 Object Size Checking](https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html), GCC Manual, 2024-08-01.

[^clang-evaluatingobjectsize]: LLVM team, [Clang Language Extensions: Evaluating Object Size](https://clang.llvm.org/docs/LanguageExtensions.html#evaluating-object-size), Clang Documentation, 2024-09-17.

[^malloc_usable_size]: Linux Man Pages team, [malloc_usable_size(3)](https://man7.org/linux/man-pages/man3/malloc_usable_size.3.html), Linux manual page, 2023-03-30.

[^kpyrd23]: kpcyrd, [Task Todo List Prepare packages for -D_FORTIFY_SOURCE=3](https://archlinux.org/todo/prepare-packages-for-d_fortify_source3/), Arch Linux Task Todo List, 2023-09-05.
Expand Down
Loading