blob: ca7a4f21c77b59e48e4c2c304f26c0fe18a217a2 [file] [log] [blame] [view]
danakj4e625fb2024-03-06 20:47:461# Preventing OOB through Unsafe Buffers errors (aka Spanification)
2
3Out-of-bounds (OOB) security bugs commonly happen through pointers
4which have no bounds checks associated with them. We prevent such
5bugs by always using containers.
6
7Most pointers are unowned references into an array (or vector)
8and the most appropriate replacement for the pointer is
danakje7db1e3f32024-04-16 20:43:249[`base::span`](../base/containers/span.h).
danakj4e625fb2024-03-06 20:47:4610
danakje7db1e3f32024-04-16 20:43:2411Entire directories have been opted out of unsafe pointer usage
12warnings through the
danakj4e625fb2024-03-06 20:47:4613[`//build/config/unsafe_buffers_paths.txt`](../build/config/unsafe_buffers_paths.txt)
danakje7db1e3f32024-04-16 20:43:2414file. As we convert unsafe pointers to safe constructs like
15`base::span`, `base::HeapArray` and `std::vector`, we will
16remove paths from that file to enable the warnings across the
17codebase.
18
19## Controlling warnings for a single file
20
21Warnings can be disabled for a single (C++ source or header) file by
22writing `#pragma allow_unsafe_buffers` anywhere in the file. This can
23be used to mark future work to drive down over time.
24
25Warnings can be enabled for a single (C++ source or header) file by
26writing `#pragma check_unsafe_buffers` anywhere in the file. It's recommended
27to place the pragma directly below the copyright and before any `#include`
28directives. This can be used to work through files in a directory
29incrementally. Though it's preferable to instead remove the whole directory
30from opt-out in the
31[`//build/config/unsafe_buffers_paths.txt`](../build/config/unsafe_buffers_paths.txt)
32file, and temporarily mark any files with `#pragma allow_unsafe_buffers`
33that need it.
danakj4e625fb2024-03-06 20:47:4634
35# Functions with array pointer parameters
36
37Functions that receive a pointer into an array may read
38or write out of bounds of the pointer if given a pointer that
39is incorrectly sized. Such functions should be marked with the
danakje7db1e3f32024-04-16 20:43:2440`UNSAFE_BUFFER_USAGE` attribute macro.
danakj4e625fb2024-03-06 20:47:4641
42The same is true for functions that accept an iterator instead
danakje7db1e3f32024-04-16 20:43:2443of a range type. Some examples of each are `memcpy()` and
44`std::copy()`.
danakj4e625fb2024-03-06 20:47:4645
46Calling such functions is unsafe and should generally be avoided.
47Instead, replace such functions with an API built on base::span
48or other range types which prevents any chance of OOB memory
49access. For instance, replace `memcpy()`, `std::copy()` and
50`std::ranges::copy()` with `base::span::copy_from()`. And
51replace `memset()` with `std::ranges::fill()`.
52
53# Writing unsafe data structures with pointers
54
55TODO: Write about `UNSAFE_BUFFERS()` for rare exceptions where
56the correctness of pointer bounds can be fully explained and
danakje7db1e3f32024-04-16 20:43:2457encapsulated, such as within a data structure or when working
58with Operating System and C-like APIs.