Title: fortify-headers 2.0
Date: 2023-12-12 23:30

8 months ago, I started to contribute to [fortify-headers](https://git.2f30.org/fortify-headers/),
a standalone [fortify-source](https://gcc.gnu.org/legacy-ml/gcc-patches/2004-09/msg02055.html) implementation,
with the goal of implementing `FORTIFY_SOURCE=3`, since the current version
only implemented `FORTIFY_SOURCE=2`. I reached out to
[sin](https://u.2f30.org/sin/), the original maintainer, to ask if he was
interested in my changes, and he told me the project wasn't maintained
anymore. But he would be happy to give me the commit bit instead. I spent
some months [writing code](https://github.com/jvoisin/fortify-headers) before
accepting, to see if it would be a good idea: Would I be able to maintain it?
To improve it? Add more features? and so on. Turns out the answer is yes, and
I'm thus happy to announce the immediate availability of [fortify-headers
2.0](https://git.2f30.org/fortify-headers/refs.html)!

## Changelog

- Added clang support, based on [q66](https://github.com/q66)'s patches.
- Fixed a 64b-related incompatibility around `ppoll` 
- Added a ton of tests, with [around 90% of coverage](https://jvoisin.github.io/fortify-headers/)
- Made use of `__builtin_dynamic_object_size` when `FORTIFY_SOURCE=3` is used,
  instead of `__builtin_object_size`.
- Made use of [attributes](https://clang.llvm.org/docs/AttributeReference.html):
  [alloc\_size](https://clang.llvm.org/docs/AttributeReference.html#alloc-size),
  [diagnose\_as\_builtin](https://clang.llvm.org/docs/AttributeReference.html#diagnose-as-builtin),
  [diagnose\_if](https://clang.llvm.org/docs/AttributeReference.html#diagnose-if),
  [format](https://clang.llvm.org/docs/AttributeReference.html#format),
  [malloc](https://clang.llvm.org/docs/AttributeReference.html#malloc),
  [warn\_unused\_result](https://clang.llvm.org/docs/AttributeReference.html#nodiscard-warn-unused-result),
  …
- Added some missing functions, like `calloc`, `fdopen`, `fmemopen`, `fprintf`,
  `malloc`, `memchr`, `popen`, `printf`, `qsort`, `umask`, …
- Added continuous integration, both on clang and gcc, covering the whole range
  of supported versions across the latest Ubuntu LTS.

## Implementation details

Since this is a pretty uncommon piece of software, friends of mine have been
asking me details about the involved black magic.
While it's possible to overload functions with the
[overloadable](https://clang.llvm.org/docs/AttributeReference.html#overloadable)
attribute in C, there isn't really something similar for drive-by overloading.
Fortunately, it's possible to hack an equivalent by combining
[`#include_next`](https://gcc.gnu.org/onlinedocs/cpp/Wrapper-Headers.html) with
the following macros:

```C
#define _FORTIFY_STR(s) #s
#define _FORTIFY_ORIG(p, fn) __typeof__(fn) __orig_##fn __asm__(_FORTIFY_STR(p) #fn)
#define _FORTIFY_FNB(fn) _FORTIFY_ORIG(__USER_LABEL_PREFIX__, fn)
#define _FORTIFY_FN(fn) _FORTIFY_FNB(fn); _FORTIFY_INLINE
```

This makes the original function available when prefixed with `__orig`,
while allowing overloading.
On clang, the [`pass_object_size`/`pass_dynamic_object_size`](https://clang.llvm.org/docs/AttributeReference.html#pass-object-size-pass-dynamic-object-size)
attribute is used to pass down arguments size; the assembly label preventing
weird [mangling](https://en.wikipedia.org/wiki/Name_mangling) issues. Since
it's only a label, despite being assembly, it's still portable across various
architectures. The `_FORTIFY_INLINE` macro contains all possible "please inline this
function" directives as possible, to avoid polluting the symbols.

There is of course a ton of `#ifdef`/`#if __has_atribute`/… to work around various
compiler intrinsics, like clang missing `__builtin_va_arg_pack` or gcc missing
`diagnose_if`, so that fortify-headers will always make use of the most
features available.

It is indeed a particularly gross pile of hacks,
but this is C, also known as "nice things and why we can't have them."

Thanks to [sin](https://u.2f30.org/sin/) for creating the project and
maintaining it for years, [strcat](https://daniel.micay.dev) for his inspiring
work on fortifying [bionic](https://en.wikipedia.org/wiki/Bionic_(software)),
[q66](https://github.com/q66) for his clang patches and general support,
the friendly people from [2f30](https://2f30.org) for their patience,
[Serge Sans Paille](http://serge.liyun.free.fr/serge/) for his [testsuite](https://github.com/serge-sans-paille/fortify-test-suite),
[kevans](https://people.freebsd.org/~kevans/) for his work on fortifying
[FreeBSD's libc](https://reviews.freebsd.org/D32306),
Red Hat from pushing `FORTIFY_SOURCE=2` and `FORTIFY_SOURCE=3` forward,
...
