Skip to content

Commit 087f9c5

Browse files
committed
Add fd_args attributes to annotations guide
Signed-off-by: Thomas Nyman <[email protected]>
1 parent 83ec651 commit 087f9c5

File tree

1 file changed

+42
-3
lines changed

1 file changed

+42
-3
lines changed

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

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,9 @@ Table 1: Recommended attributes
3535
| `ownership_holds(`_`allocation-type`_`,` _`ptr-index`_`)` | Clang 20.1.0 | Function | Mark function taking responsibility of deallocation for _`allocation-type`_. |
3636
| `alloc_size(`_`size-index`_`)`<br/>`alloc_size(`_`size-index-1`_`,`_`size-index-2`_`)` | GCC 2.95.3<br/>Clang 4.0.0 | Function | Mark positional arguments holding the allocation size that the returned pointer points to. |
3737
| `access(`_`mode`_`,`_`ref-pos`_`)`<br/>`access(`_`mode`_`,` _`ref-pos`_`,` _`size-pos`_`)` | GCC 10.0.0 | Function | Mark access restrictions for positional argument. |
38-
| `fd_arg(N)` | GCC 13 | Function | Argument N is an open file descriptor. |
39-
| `fd_arg_read(N)` | GCC 13 | Function | Argument N is an open file descriptor that can be read from. |
40-
| `fd_arg_write(N)` | GCC 13 | Function | Argument N is an open file descriptor that can be written to. |
38+
| `fd_arg(`_`fd-index`_`)` | GCC 13.1.0 | Function | Mark open file descriptors in positional arguments. |
39+
| `fd_arg_read(`_`fd-index`_`)` | GCC 13.1.0 | Function | Mark readable file descriptors in positional arguments. |
40+
| `fd_arg_write(`_`fd-index`_`)` | GCC 13.1.0 | Function | Mark writable file descriptors in positional arguments. |
4141
| `noreturn` | GCC 2.95.3<br/>Clang 4.0.0 | Function | The function does not return. |
4242
| `tainted_args` | GCC 12 | Function or function pointer | Function needs sanitization of its arguments. Used by `-fanalyzer=taint` |
4343

@@ -225,3 +225,42 @@ void to_uppercase(char *buffer, size_t size) __attribute__((access(read_write, 1
225225
[^gcc-access]: GCC team, [Using the GNU Compiler Collection (GCC): 6.35.1 Common Function Attributes: access](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-access-function-attribute), GCC Manual, 2024-08-01.
226226

227227
---
228+
229+
### Mark positional arguments holding open file desriptors
230+
231+
| Attribute | Supported since | Type | Description |
232+
|:-----------------------------------------------------------------------------------------------|:---------------------------:|:----------------------------:|:------------------------------------------------------------------------------------------------- |
233+
| `fd_arg(`_`fd-index`_`)` | GCC 13.0.0 | Function | Mark positional argument holding a valid and open file descriptor. |
234+
| `fd_arg_read(`_`fd-index`_`)` | GCC 13.0.0 | Function | Mark positional argument holding a valid, open, and readable file descriptor. |
235+
| `fd_arg_write(`_`fd-index`_`)` | GCC 13.0.0 | Function | Mark positional argument holding a valid, open, and writable file descriptor. |
236+
237+
The `fd_arg`, `fd_arg_read`, and `fd_arg_write` attributes in GCC[^gcc-fd_arg] indicate that the annotated function expects an open file descriptor as an argument. GCC’s static analyzer (`-fanalyzer`[^gcc-analyzer]) can use this information to to catch:
238+
239+
- **Access mode mismatches** (`-Wanalyzer-fd-access-mode-mismatch`) if there are code paths through which a read on a write-only file descriptor or write on a read-only file descriptor is attempted.
240+
- **Double-close conditions** (`-Wanalyzer-fd-double-close`) if there are code paths thorugh which a file descriptor can be closed more than once.
241+
- **File descriptor leaks** (`-Wanalyzer-fd-leak`) if there are code paths through which a file descriptor goes out of scope without being closed.
242+
- **Use-after-close** (`-Wanalyzer-fd-use-after-close`) if there are code paths through which a read or write is attempted on a closed file descriptor.
243+
- **Use-without-check** (`-Wanalyzer-fd-use-without-check`) if there are code paths through which a file descriptor is used without being first checked for validity.
244+
245+
The `fd_arg(`_`fd-index`_`)` form acts as a hint to the compiler that the positional argument at _`fd-index`_(using one-based indexing) must be an open file descriptor and must have been must have been checked for validity (such as by calling `fcntl(fd, F_GETFD)` on it) before usage.
246+
247+
The `fd_arg_read(`_`fd-index`_`)` form is similar to `fd_arg` but also stipulates that the file descriptor must not have been opened as write-only.
248+
249+
The `fd_arg_write(`_`fd-index`_`)` form is similar to `fd_arg` but also stipulates that the file descriptor must not have been opened as read-only.
250+
251+
#### Example usage
252+
253+
~~~c
254+
// Denotes that use_file expects fd to be a valid and open file descriptor
255+
void use_file (int fd) __attribute__ ((fd_arg (1)));
256+
257+
// Denotes that write_to_file expects fd to be a valid, open, and writable file descriptor
258+
void write_to_file (int fd, void *src, size_t size) __attribute__ ((fd_arg_write (1)));
259+
260+
// Denotes that read_from_file expects fd to be a valid, open, and readable file descriptor
261+
void read_from_file (int fd, void *dst, size_t size) __attribute__ ((fd_arg_read (1)));
262+
~~~
263+
264+
[[Extended example at Compiler Explorer](https://godbolt.org/z/T66Wj5YKv)]
265+
266+
[^gcc-fd_arg]: GCC team, [Using the GNU Compiler Collection (GCC): 6.35.1 Common Function Attributes: fd_arg](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-fd_005farg-function-attribute), GCC Manual, 2024-08-01.

0 commit comments

Comments
 (0)