1 ==================================================
2 ``-fbounds-safety``: Enforcing bounds safety for C
3 ==================================================
11 **NOTE:** This is a design document and the feature is not available for users yet.
12 Please see :doc:`BoundsSafetyImplPlans` for more details.
14 ``-fbounds-safety`` is a C extension to enforce bounds safety to prevent
15 out-of-bounds (OOB) memory accesses, which remain a major source of security
16 vulnerabilities in C. ``-fbounds-safety`` aims to eliminate this class of bugs
17 by turning OOB accesses into deterministic traps.
19 The ``-fbounds-safety`` extension offers bounds annotations that programmers can
20 use to attach bounds to pointers. For example, programmers can add the
21 ``__counted_by(N)`` annotation to parameter ``ptr``, indicating that the pointer
22 has ``N`` valid elements:
26 void foo(int *__counted_by(N) ptr, size_t N);
28 Using this bounds information, the compiler inserts bounds checks on every
29 pointer dereference, ensuring that the program does not access memory outside
30 the specified bounds. The compiler requires programmers to provide enough bounds
31 information so that the accesses can be checked at either run time or compile
32 time — and it rejects code if it cannot.
34 The most important contribution of ``-fbounds-safety`` is how it reduces the
35 programmer's annotation burden by reconciling bounds annotations at ABI
36 boundaries with the use of implicit wide pointers (a.k.a. "fat" pointers) that
37 carry bounds information on local variables without the need for annotations. We
38 designed this model so that it preserves ABI compatibility with C while
39 minimizing adoption effort.
41 The ``-fbounds-safety`` extension has been adopted on millions of lines of
42 production C code and proven to work in a consumer operating system setting. The
43 extension was designed to enable incremental adoption — a key requirement in
44 real-world settings where modifying an entire project and its dependencies all
45 at once is often not possible. It also addresses multiple of other practical
46 challenges that have made existing approaches to safer C dialects difficult to
47 adopt, offering these properties that make it widely adoptable in practice:
49 * It is designed to preserve the Application Binary Interface (ABI).
50 * It interoperates well with plain C code.
51 * It can be adopted partially and incrementally while still providing safety
53 * It is a conforming extension to C.
54 * Consequently, source code that adopts the extension can continue to be
55 compiled by toolchains that do not support the extension (CAVEAT: this still
56 requires inclusion of a header file macro-defining bounds annotations to
58 * It has a relatively low adoption cost.
60 This document discusses the key designs of ``-fbounds-safety``. The document is
61 subject to be actively updated with a more detailed specification.
69 ``-fbounds-safety`` ensures that pointers are not used to access memory beyond
70 their bounds by performing bounds checking. If a bounds check fails, the program
71 will deterministically trap before out-of-bounds memory is accessed.
73 In our model, every pointer has an explicit or implicit bounds attribute that
74 determines its bounds and ensures guaranteed bounds checking. Consider the
75 example below where the ``__counted_by(count)`` annotation indicates that
76 parameter ``p`` points to a buffer of integers containing ``count`` elements. An
77 off-by-one error is present in the loop condition, leading to ``p[i]`` being
78 out-of-bounds access during the loop's final iteration. The compiler inserts a
79 bounds check before ``p`` is dereferenced to ensure that the access remains
80 within the specified bounds.
84 void fill_array_with_indices(int *__counted_by(count) p, unsigned count) {
85 // off-by-one error (i < count)
86 for (unsigned i = 0; i <= count; ++i) {
87 // bounds check inserted:
88 // if (i >= count) trap();
93 A bounds annotation defines an invariant for the pointer type, and the model
94 ensures that this invariant remains true. In the example below, pointer ``p``
95 annotated with ``__counted_by(count)`` must always point to a memory buffer
96 containing at least ``count`` elements of the pointee type. Changing the value
97 of ``count``, like in the example below, may violate this invariant and permit
98 out-of-bounds access to the pointer. To avoid this, the compiler employs
99 compile-time restrictions and emits run-time checks as necessary to ensure the
100 new count value doesn't exceed the actual length of the buffer. Section
101 `Maintaining correctness of bounds annotations`_ provides more details about
102 this programming model.
108 void foo(int *__counted_by(count) p, size_t count) {
109 count++; // may violate the invariant of __counted_by
110 count--; // may violate the invariant of __counted_by if count was 0.
111 count = g; // may violate the invariant of __counted_by
112 // depending on the value of `g`.
115 The requirement to annotate all pointers with explicit bounds information could
116 present a significant adoption burden. To tackle this issue, the model
117 incorporates the concept of a "wide pointer" (a.k.a. fat pointer) – a larger
118 pointer that carries bounds information alongside the pointer value. Utilizing
119 wide pointers can potentially reduce the adoption burden, as it contains bounds
120 information internally and eliminates the need for explicit bounds annotations.
121 However, wide pointers differ from standard C pointers in their data layout,
122 which may result in incompatibilities with the application binary interface
123 (ABI). Breaking the ABI complicates interoperability with external code that has
124 not adopted the same programming model.
126 ``-fbounds-safety`` harmonizes the wide pointer and the bounds annotation
127 approaches to reduce the adoption burden while maintaining the ABI. In this
128 model, local variables of pointer type are implicitly treated as wide pointers,
129 allowing them to carry bounds information without requiring explicit bounds
130 annotations. Please note that this approach doesn't apply to function parameters
131 which are considered ABI-visible. As local variables are typically hidden from
132 the ABI, this approach has a marginal impact on it. In addition,
133 ``-fbounds-safety`` employs compile-time restrictions to prevent implicit wide
134 pointers from silently breaking the ABI (see `ABI implications of default bounds
135 annotations`_). Pointers associated with any other variables, including function
136 parameters, are treated as single object pointers (i.e., ``__single``), ensuring
137 that they always have the tightest bounds by default and offering a strong
138 bounds safety guarantee.
140 By implementing default bounds annotations based on ABI visibility, a
141 considerable portion of C code can operate without modifications within this
142 programming model, reducing the adoption burden.
144 The rest of the section will discuss individual bounds annotations and the
145 programming model in more detail.
150 Annotation for pointers to a single object
151 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
153 The C language allows pointer arithmetic on arbitrary pointers and this has been
154 a source of many bounds safety issues. In practice, many pointers are merely
155 pointing to a single object and incrementing or decrementing such a pointer
156 immediately makes the pointer go out-of-bounds. To prevent this unsafety,
157 ``-fbounds-safety`` provides the annotation ``__single`` that causes pointer
158 arithmetic on annotated pointers to be a compile time error.
160 * ``__single`` : indicates that the pointer is either pointing to a single
161 object or null. Hence, pointers with ``__single`` do not permit pointer
162 arithmetic nor being subscripted with a non-zero index. Dereferencing a
163 ``__single`` pointer is allowed but it requires a null check. Upper and lower
164 bounds checks are not required because the ``__single`` pointer should point
165 to a valid object unless it's null.
167 ``__single`` is the default annotation for ABI-visible pointers. This
168 gives strong security guarantees in that these pointers cannot be incremented or
169 decremented unless they have an explicit, overriding bounds annotation that can
170 be used to verify the safety of the operation. The compiler issues an error when
171 a ``__single`` pointer is utilized for pointer arithmetic or array access, as
172 these operations would immediately cause the pointer to exceed its bounds.
173 Consequently, this prompts programmers to provide sufficient bounds information
174 to pointers. In the following example, the pointer on parameter p is
175 single-by-default, and is employed for array access. As a result, the compiler
176 generates an error suggesting to add ``__counted_by`` to the pointer.
180 void fill_array_with_indices(int *p, unsigned count) {
181 for (unsigned i = 0; i < count; ++i) {
187 External bounds annotations
188 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
190 "External" bounds annotations provide a way to express a relationship between a
191 pointer variable and another variable (or expression) containing the bounds
192 information of the pointer. In the following example, ``__counted_by(count)``
193 annotation expresses the bounds of parameter p using another parameter count.
194 This model works naturally with many C interfaces and structs because the bounds
195 of a pointer is often available adjacent to the pointer itself, e.g., at another
196 parameter of the same function prototype, or at another field of the same struct
201 void fill_array_with_indices(int *__counted_by(count) p, size_t count) {
203 for (size_t i = 0; i <= count; ++i)
207 External bounds annotations include ``__counted_by``, ``__sized_by``, and
208 ``__ended_by``. These annotations do not change the pointer representation,
209 meaning they do not have ABI implications.
211 * ``__counted_by(N)`` : The pointer points to memory that contains ``N``
212 elements of pointee type. ``N`` is an expression of integer type which can be
213 a simple reference to declaration, a constant including calls to constant
214 functions, or an arithmetic expression that does not have side effect. The
215 ``__counted_by`` annotation cannot apply to pointers to incomplete types or
216 types without size such as ``void *``. Instead, ``__sized_by`` can be used to
217 describe the byte count.
218 * ``__sized_by(N)`` : The pointer points to memory that contains ``N`` bytes.
219 Just like the argument of ``__counted_by``, ``N`` is an expression of integer
220 type which can be a constant, a simple reference to a declaration, or an
221 arithmetic expression that does not have side effects. This is mainly used for
222 pointers to incomplete types or types without size such as ``void *``.
223 * ``__ended_by(P)`` : The pointer has the upper bound of value ``P``, which is
224 one past the last element of the pointer. In other words, this annotation
225 describes a range that starts with the pointer that has this annotation and
226 ends with ``P`` which is the argument of the annotation. ``P`` itself may be
227 annotated with ``__ended_by(Q)``. In this case, the end of the range extends
228 to the pointer ``Q``. This is used for "iterator" support in C where you're
229 iterating from one pointer value to another until a final pointer value is
230 reached (and the final pointer value is not dereferencable).
232 Accessing a pointer outside the specified bounds causes a run-time trap or a
233 compile-time error. Also, the model maintains correctness of bounds annotations
234 when the pointer and/or the related value containing the bounds information are
235 updated or passed as arguments. This is done by compile-time restrictions or
236 run-time checks (see `Maintaining correctness of bounds annotations`_
237 for more detail). For instance, initializing ``buf`` with ``null`` while
238 assigning non-zero value to ``count``, as shown in the following example, would
239 violate the ``__counted_by`` annotation because a null pointer does not point to
240 any valid memory location. To avoid this, the compiler produces either a
241 compile-time error or run-time trap.
245 void null_with_count_10(int *__counted_by(count) buf, unsigned count) {
247 // This is not allowed as it creates a null pointer with non-zero length
251 However, there are use cases where a pointer is either a null pointer or is
252 pointing to memory of the specified size. To support this idiom,
253 ``-fbounds-safety`` provides ``*_or_null`` variants,
254 ``__counted_by_or_null(N)``, ``__sized_by_or_null(N)``, and
255 ``__ended_by_or_null(P)``. Accessing a pointer with any of these bounds
256 annotations will require an extra null check to avoid a null pointer
259 Internal bounds annotations
260 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
262 A wide pointer (sometimes known as a "fat" pointer) is a pointer that carries
263 additional bounds information internally (as part of its data). The bounds
264 require additional storage space making wide pointers larger than normal
265 pointers, hence the name "wide pointer". The memory layout of a wide pointer is
266 equivalent to a struct with the pointer, upper bound, and (optionally) lower
267 bound as its fields as shown below.
271 struct wide_pointer_datalayout {
272 void* pointer; // Address used for dereferences and pointer arithmetic
273 void* upper_bound; // Points one past the highest address that can be
275 void* lower_bound; // (Optional) Points to lowest address that can be
279 Even with this representational change, wide pointers act syntactically as
280 normal pointers to allow standard pointer operations, such as pointer
281 dereference (``*p``), array subscript (``p[i]``), member access (``p->``), and
282 pointer arithmetic, with some restrictions on bounds-unsafe uses.
284 ``-fbounds-safety`` has a set of "internal" bounds annotations to turn pointers
285 into wide pointers. These are ``__bidi_indexable`` and ``__indexable``. When a
286 pointer has either of these annotations, the compiler changes the pointer to the
287 corresponding wide pointer. This means these annotations will break the ABI and
288 will not be compatible with plain C, and thus they should generally not be used
291 * ``__bidi_indexable`` : A pointer with this annotation becomes a wide pointer
292 to carry the upper bound and the lower bound, the layout of which is
293 equivalent to ``struct { T *ptr; T *upper_bound; T *lower_bound; };``. As the
294 name indicates, pointers with this annotation are "bidirectionally indexable",
295 meaning that they can be indexed with either a negative or a positive offset
296 and the pointers can be incremented or decremented using pointer arithmetic. A
297 ``__bidi_indexable`` pointer is allowed to hold an out-of-bounds pointer
298 value. While creating an OOB pointer is undefined behavior in C,
299 ``-fbounds-safety`` makes it well-defined behavior. That is, pointer
300 arithmetic overflow with ``__bidi_indexable`` is defined as equivalent of
301 two's complement integer computation, and at the LLVM IR level this means
302 ``getelementptr`` won't get ``inbounds`` keyword. Accessing memory using the
303 OOB pointer is prevented via a run-time bounds check.
305 * ``__indexable`` : A pointer with this annotation becomes a wide pointer
306 carrying the upper bound (but no explicit lower bound), the layout of which is
307 equivalent to ``struct { T *ptr; T *upper_bound; };``. Since ``__indexable``
308 pointers do not have a separate lower bound, the pointer value itself acts as
309 the lower bound. An ``__indexable`` pointer can only be incremented or indexed
310 in the positive direction. Indexing it in the negative direction will trigger
311 a compile-time error. Otherwise, the compiler inserts a run-time
312 check to ensure pointer arithmetic doesn't make the pointer smaller than the
313 original ``__indexable`` pointer (Note that ``__indexable`` doesn't have a
314 lower bound so the pointer value is effectively the lower bound). As pointer
315 arithmetic overflow will make the pointer smaller than the original pointer,
316 it will cause a trap at runtime. Similar to ``__bidi_indexable``, an
317 ``__indexable`` pointer is allowed to have a pointer value above the upper
318 bound and creating such a pointer is well-defined behavior. Dereferencing such
319 a pointer, however, will cause a run-time trap.
321 * ``__bidi_indexable`` offers the best flexibility out of all the pointer
322 annotations in this model, as ``__bidi_indexable`` pointers can be used for
323 any pointer operation. However, this comes with the largest code size and
324 memory cost out of the available pointer annotations in this model. In some
325 cases, use of the ``__bidi_indexable`` annotation may be duplicating bounds
326 information that exists elsewhere in the program. In such cases, using
327 external bounds annotations may be a better choice.
329 ``__bidi_indexable`` is the default annotation for non-ABI visible pointers,
330 such as local pointer variables — that is, if the programmer does not specify
331 another bounds annotation, a local pointer variable is implicitly
332 ``__bidi_indexable``. Since ``__bidi_indexable`` pointers automatically carry
333 bounds information and have no restrictions on kinds of pointer operations that
334 can be used with these pointers, most code inside a function works as is without
335 modification. In the example below, ``int *buf`` doesn't require manual
336 annotation as it's implicitly ``int *__bidi_indexable buf``, carrying the bounds
337 information passed from the return value of malloc, which is necessary to insert
338 bounds checking for ``buf[i]``.
342 void *__sized_by(size) malloc(size_t size);
344 int *__counted_by(n) get_array_with_0_to_n_1(size_t n) {
345 int *buf = malloc(sizeof(int) * n);
346 for (size_t i = 0; i < n; ++i)
351 Annotations for sentinel-delimited arrays
352 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
354 A C string is an array of characters. The null terminator — the first null
355 character ('\0') element in the array — marks the end of the string.
356 ``-fbounds-safety`` provides ``__null_terminated`` to annotate C strings and the
357 generalized form ``__terminated_by(T)`` to annotate pointers and arrays with an
358 end marked by a sentinel value. The model prevents dereferencing a
359 ``__terminated_by`` pointer beyond its end. Calculating the location of the end
360 (i.e., the address of the sentinel value), requires reading the entire array in
361 memory and would have some performance costs. To avoid an unintended performance
362 hit, the model puts some restrictions on how these pointers can be used.
363 ``__terminated_by`` pointers cannot be indexed and can only be incremented one
364 element at a time. To allow these operations, the pointers must be explicitly
365 converted to ``__indexable`` pointers using the intrinsic function
366 ``__unsafe_terminated_by_to_indexable(P, T)`` (or
367 ``__unsafe_null_terminated_to_indexable(P)``) which converts the
368 ``__terminated_by`` pointer ``P`` to an ``__indexable`` pointer.
370 * ``__null_terminated`` : The pointer or array is terminated by ``NULL`` or
371 ``0``. Modifying the terminator or incrementing the pointer beyond it is
372 prevented at run time.
374 * ``__terminated_by(T)`` : The pointer or array is terminated by ``T`` which is
375 a constant expression. Accessing or incrementing the pointer beyond the
376 terminator is not allowed. This is a generalization of ``__null_terminated``
377 which is defined as ``__terminated_by(0)``.
379 Annotation for interoperating with bounds-unsafe code
380 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
382 A pointer with the ``__unsafe_indexable`` annotation behaves the same as a plain
383 C pointer. That is, the pointer does not have any bounds information and pointer
384 operations are not checked.
386 ``__unsafe_indexable`` can be used to mark pointers from system headers or
387 pointers from code that has not adopted -fbounds safety. This enables
388 interoperation between code using ``-fbounds-safety`` and code that does not.
390 Default pointer types
391 ---------------------
393 ABI visibility and default annotations
394 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
396 Requiring ``-fbounds-safety`` adopters to add bounds annotations to all pointers
397 in the codebase would be a significant adoption burden. To avoid this and to
398 secure all pointers by default, ``-fbounds-safety`` applies default bounds
399 annotations to pointer types.
400 Default annotations apply to pointer types of declarations
402 ``-fbounds-safety`` applies default bounds annotations to pointer types used in
403 declarations. The default annotations are determined by the ABI visibility of
404 the pointer. A pointer type is ABI-visible if changing its size or
405 representation affects the ABI. For instance, changing the size of a type used
406 in a function parameter will affect the ABI and thus pointers used in function
407 parameters are ABI-visible pointers. On the other hand, changing the types of
408 local variables won't have such ABI implications. Hence, ``-fbounds-safety``
409 considers the outermost pointer types of local variables as non-ABI visible. The
410 rest of the pointers such as nested pointer types, pointer types of global
411 variables, struct fields, and function prototypes are considered ABI-visible.
413 All ABI-visible pointers are treated as ``__single`` by default unless annotated
414 otherwise. This default both preserves ABI and makes these pointers safe by
415 default. This behavior can be controlled with macros, i.e.,
416 ``__ptrcheck_abi_assume_*ATTR*()``, to set the default annotation for
417 ABI-visible pointers to be either ``__single``, ``__bidi_indexable``,
418 ``__indexable``, or ``__unsafe_indexable``. For instance,
419 ``__ptrcheck_abi_assume_unsafe_indexable()`` will make all ABI-visible pointers
420 be ``__unsafe_indexable``. Non-ABI visible pointers — the outermost pointer
421 types of local variables — are ``__bidi_indexable`` by default, so that these
422 pointers have the bounds information necessary to perform bounds checks without
423 the need for a manual annotation. All ``const char`` pointers or any typedefs
424 equivalent to ``const char`` pointers are ``__null_terminated`` by default. This
425 means that ``char8_t`` is ``unsigned char`` so ``const char8_t *`` won't be
426 ``__null_terminated`` by default. Similarly, ``const wchar_t *`` won't be
427 ``__null_terminated`` by default unless the platform defines it as ``typedef
428 char wchar_t``. Please note, however, that the programmers can still explicitly
429 use ``__null_terminated`` in any other pointers, e.g., ``char8_t
430 *__null_terminated``, ``wchar_t *__null_terminated``, ``int
431 *__null_terminated``, etc. if they should be treated as ``__null_terminated``.
432 The same applies to other annotations.
433 In system headers, the default pointer attribute for ABI-visible pointers is set
434 to ``__unsafe_indexable`` by default.
436 The ``__ptrcheck_abi_assume_*ATTR*()`` macros are defined as pragmas in the
437 toolchain header (See `Portability with toolchains that do not support the
438 extension`_ for more details about the toolchain header):
442 #define __ptrcheck_abi_assume_single() \
443 _Pragma("clang abi_ptr_attr set(single)")
445 #define __ptrcheck_abi_assume_indexable() \
446 _Pragma("clang abi_ptr_attr set(indexable)")
448 #define __ptrcheck_abi_assume_bidi_indexable() \
449 _Pragma("clang abi_ptr_attr set(bidi_indexable)")
451 #define __ptrcheck_abi_assume_unsafe_indexable() \
452 _Pragma("clang abi_ptr_attr set(unsafe_indexable)")
455 ABI implications of default bounds annotations
456 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
458 Although simply modifying types of a local variable doesn't normally impact the
459 ABI, taking the address of such a modified type could create a pointer type that
460 has an ABI mismatch. Looking at the following example, ``int *local`` is
461 implicitly ``int *__bidi_indexable`` and thus the type of ``&local`` is a
462 pointer to ``int *__bidi_indexable``. On the other hand, in ``void foo(int
463 **)``, the parameter type is a pointer to ``int *__single`` (i.e., ``void
464 foo(int *__single *__single)``) (or a pointer to ``int *__unsafe_indexable`` if
465 it's from a system header). The compiler reports an error for casts between
466 pointers whose elements have incompatible pointer attributes. This way,
467 ``-fbounds-safety`` prevents pointers that are implicitly ``__bidi_indexable``
468 from silently escaping thereby breaking the ABI.
476 // error: passing 'int *__bidi_indexable*__bidi_indexable' to parameter of
477 // incompatible nested pointer type 'int *__single*__single'
481 A local variable may still be exposed to the ABI if ``typeof()`` takes the type
482 of local variable to define an interface as shown in the following example.
487 void bar(int *) { ... }
491 int *p; // implicitly `int *__bidi_indexable p`
492 extern void bar(typeof(p)); // creates an interface of type
493 // `void bar(int *__bidi_indexable)`
496 Doing this may break the ABI if the parameter is not ``__bidi_indexable`` at the
497 definition of function ``bar()`` which is likely the case because parameters are
498 ``__single`` by default without an explicit annotation.
500 In order to avoid an implicitly wide pointer from silently breaking the ABI, the
501 compiler reports a warning when ``typeof()`` is used on an implicit wide pointer
502 at any ABI visible context (e.g., function prototype, struct definition, etc.).
504 .. _Default pointer types in typeof:
506 Default pointer types in ``typeof()``
507 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
509 When ``typeof()`` takes an expression, it respects the bounds annotation on
510 the expression type, including the bounds annotation is implcit. For example,
511 the global variable ``g`` in the following code is implicitly ``__single`` so
512 ``typeof(g)`` gets ``char *__single``. The similar is true for the parameter
513 ``p``, so ``typeof(p)`` returns ``void *__single``. The local variable ``l`` is
514 implicitly ``__bidi_indexable``, so ``typeof(l)`` becomes
515 ``int *__bidi_indexable``.
519 char *g; // typeof(g) == char *__single
522 // typeof(p) == void *__single
524 int *l; // typeof(l) == int *__bidi_indexable
527 When the type of expression has an "external" bounds annotation, e.g.,
528 ``__sized_by``, ``__counted_by``, etc., the compiler may report an error on
529 ``typeof`` if the annotation creates a dependency with another declaration or
530 variable. For example, the compiler reports an error on ``typeof(p1)`` shown in
531 the following code because allowing it can potentially create another type
532 dependent on the parameter ``size`` in a different context (Please note that an
533 external bounds annotation on a parameter may only refer to another parameter of
534 the same function). On the other hand, ``typeof(p2)`` works resulting in ``int
535 *__counted_by(10)``, since it doesn't depend on any other declaration.
537 .. TODO: add a section describing constraints on external bounds annotations
541 void foo(int *__counted_by(size) p1, size_t size) {
542 // typeof(p1) == int *__counted_by(size)
543 // -> a compiler error as it tries to create another type
544 // dependent on `size`.
546 int *__counted_by(10) p2; // typeof(p2) == int *__counted_by(10)
551 When ``typeof()`` takes a type name, the compiler doesn't apply an implicit
552 bounds annotation on the named pointer types. For example, ``typeof(int*)``
553 returns ``int *`` without any bounds annotation. A bounds annotation may be
554 added after the fact depending on the context. In the following example,
555 ``typeof(int *)`` returns ``int *`` so it's equivalent as the local variable is
556 declared as ``int *l``, so it eventually becomes implicitly
557 ``__bidi_indexable``.
562 typeof(int *) l; // `int *__bidi_indexable` (same as `int *l`)
565 The programmers can still explicitly add a bounds annotation on the types named
566 inside ``typeof``, e.g., ``typeof(int *__bidi_indexable)``, which evaluates to
567 ``int *__bidi_indexable``.
570 Default pointer types in ``sizeof()``
571 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
573 When ``sizeof()`` takes a type name, the compiler doesn't apply an implicit
574 bounds annotation on the named pointer types. This means if a bounds annotation
575 is not specified, the evaluated pointer type is treated identically to a plain C
576 pointer type. Therefore, ``sizeof(int*)`` remains the same with or without
577 ``-fbounds-safety``. That said, programmers can explicitly add attribute to the
578 types, e.g., ``sizeof(int *__bidi_indexable)``, in which case the sizeof
579 evaluates to the size of type ``int *__bidi_indexable`` (the value equivalent to
580 ``3 * sizeof(int*)``).
582 When ``sizeof()`` takes an expression, i.e., ``sizeof(expr``, it behaves as
583 ``sizeof(typeof(expr))``, except that ``sizeof(expr)`` does not report an error
584 with ``expr`` that has a type with an external bounds annotation dependent on
585 another declaration, whereas ``typeof()`` on the same expression would be an
586 error as described in :ref:`Default pointer types in typeof`.
587 The following example describes this behavior.
591 void foo(int *__counted_by(size) p, size_t size) {
592 // sizeof(p) == sizeof(int *__counted_by(size)) == sizeof(int *)
596 Default pointer types in ``alignof()``
597 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
599 ``alignof()`` only takes a type name as the argument and it doesn't take an
600 expression. Similar to ``sizeof()`` and ``typeof``, the compiler doesn't apply
601 an implicit bounds annotation on the pointer types named inside ``alignof()``.
602 Therefore, ``alignof(T *)`` remains the same with or without
603 ``-fbounds-safety``, evaluating into the alignment of the raw pointer ``T *``.
604 The programmers can explicitly add a bounds annotation to the types, e.g.,
605 ``alignof(int *__bidi_indexable)``, which returns the alignment of ``int
606 *__bidi_indexable``. A bounds annotation including an internal bounds annotation
607 (i.e., ``__indexable`` and ``__bidi_indexable``) doesn't affect the alignment of
608 the original pointer. Therefore, ``alignof(int *__bidi_indexable)`` is equal to
612 Default pointer types used in C-style casts
613 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
615 A pointer type used in a C-style cast (e.g., ``(int *)src``) inherits the same
616 pointer attribute in the type of src. For instance, if the type of src is ``T
617 *__single`` (with ``T`` being an arbitrary C type), ``(int *)src`` will be ``int
618 *__single``. The reasoning behind this behavior is so that a C-style cast
619 doesn't introduce any unexpected side effects caused by an implicit cast of
622 Pointer casts can have explicit bounds annotations. For instance, ``(int
623 *__bidi_indexable)src`` casts to ``int *__bidi_indexable`` as long as src has a
624 bounds annotation that can implicitly convert to ``__bidi_indexable``. If
625 ``src`` has type ``int *__single``, it can implicitly convert to ``int
626 *__bidi_indexable`` which then will have the upper bound pointing to one past
627 the first element. However, if src has type ``int *__unsafe_indexable``, the
628 explicit cast ``(int *__bidi_indexable)src`` will cause an error because
629 ``__unsafe_indexable`` cannot cast to ``__bidi_indexable`` as
630 ``__unsafe_indexable`` doesn't have bounds information. `Cast rules`_ describes
631 in more detail what kinds of casts are allowed between pointers with different
634 Default pointer types in typedef
635 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
637 Pointer types in ``typedef``\s do not have implicit default bounds annotations.
638 Instead, the bounds annotation is determined when the ``typedef`` is used. The
639 following example shows that no pointer annotation is specified in the ``typedef
640 pint_t`` while each instance of ``typedef``'ed pointer gets its bounds
641 annotation based on the context in which the type is used.
645 typedef int * pint_t; // int *
647 pint_t glob; // int *__single glob;
650 pint_t local; // int *__bidi_indexable local;
653 Pointer types in a ``typedef`` can still have explicit annotations, e.g.,
654 ``typedef int *__single``, in which case the bounds annotation ``__single`` will
655 apply to every use of the ``typedef``.
657 Array to pointer promotion to secure arrays (including VLAs)
658 ------------------------------------------------------------
660 Arrays on function prototypes
661 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
663 In C, arrays on function prototypes are promoted (or "decayed") to a pointer to
664 its first element (e.g., ``&arr[0]``). In ``-fbounds-safety``, arrays are also
665 decayed to pointers, but with the addition of an implicit bounds annotation,
666 which includes variable-length arrays (VLAs). As shown in the following example,
667 arrays on function prototypes are decalyed to corresponding ``__counted_by``
672 // Function prototype: void foo(int n, int *__counted_by(n) arr);
673 void foo(int n, int arr[n]);
675 // Function prototype: void bar(int *__counted_by(10) arr);
676 void bar(int arr[10]);
678 This means the array parameters are treated as `__counted_by` pointers within
679 the function and callers of the function also see them as the corresponding
680 `__counted_by` pointers.
682 Incomplete arrays on function prototypes will cause a compiler error unless it
683 has ``__counted_by`` annotation in its bracket.
687 void f1(int n, int arr[]); // error
689 void f3(int n, int arr[__counted_by(n)]); // ok
691 void f2(int n, int arr[n]); // ok, decays to int *__counted_by(n)
693 void f4(int n, int *__counted_by(n) arr); // ok
695 void f5(int n, int *arr); // ok, but decays to int *__single,
696 // and cannot be used for pointer arithmetic
701 In C, similar to arrays on the function prototypes, a reference to array is
702 automatically promoted (or "decayed") to a pointer to its first element (e.g.,
705 In `-fbounds-safety`, array references are promoted to ``__bidi_indexable``
706 pointers which contain the upper and lower bounds of the array, with the
707 equivalent of ``&arr[0]`` serving as the lower bound and ``&arr[array_size]``
708 (or one past the last element) serving as the upper bound. This applies to all
709 types of arrays including constant-length arrays, variable-length arrays (VLAs),
710 and flexible array members annotated with `__counted_by`.
712 In the following example, reference to ``vla`` promotes to ``int
713 *__bidi_indexable``, with ``&vla[n]`` as the upper bound and ``&vla[0]`` as the
714 lower bound. Then, it's copied to ``int *p``, which is implicitly ``int
715 *__bidi_indexable p``. Please note that value of ``n`` used to create the upper
716 bound is ``10``, not ``100``, in this case because ``10`` is the actual length
717 of ``vla``, the value of ``n`` at the time when the array is being allocated.
725 int *p = vla; // { .ptr: &vla[0], .upper: &vla[10], .lower: &vla[0] }
726 // it's `&vla[10]` because the value of `n` was 10 at the
727 // time when the array is actually allocated.
731 By promoting array references to ``__bidi_indexable``, all array accesses are
732 bounds checked in ``-fbounds-safety``, just as ``__bidi_indexable`` pointers
735 Maintaining correctness of bounds annotations
736 ---------------------------------------------
738 ``-fbounds-safety`` maintains correctness of bounds annotations by performing
739 additional checks when a pointer object and/or its related value containing the
740 bounds information is updated.
742 For example, ``__single`` expresses an invariant that the pointer must either
743 point to a single valid object or be a null pointer. To maintain this invariant,
744 the compiler inserts checks when initializing a ``__single`` pointer, as shown
745 in the following example:
749 void foo(void *__sized_by(size) vp, size_t size) {
751 // if ((int*)upper_bound(vp) - (int*)vp < sizeof(int) && !!vp) trap();
752 int *__single ip = (int *)vp;
755 Additionally, an explicit bounds annotation such as ``int *__counted_by(count)
756 buf`` defines a relationship between two variables, ``buf`` and ``count``:
757 namely, that ``buf`` has ``count`` number of elements available. This
758 relationship must hold even after any of these related variables are updated. To
759 this end, the model requires that assignments to ``buf`` and ``count`` must be
760 side by side, with no side effects between them. This prevents ``buf`` and
761 ``count`` from temporarily falling out of sync due to updates happening at a
764 The example below shows a function ``alloc_buf`` that initializes a struct that
765 members that use the ``__counted_by`` annotation. The compiler allows these
766 assignments because ``sbuf->buf`` and ``sbuf->count`` are updated side by side
767 without any side effects in between the assignments.
769 Furthermore, the compiler inserts additional run-time checks to ensure the new
770 ``buf`` has at least as many elements as the new ``count`` indicates as shown in
771 the transformed pseudo code of function ``alloc_buf()`` in the example below.
776 int *__counted_by(count) buf;
780 void alloc_buf(sized_buf_t *sbuf, sized_t nelems) {
781 sbuf->buf = (int *)malloc(sizeof(int) * nelems);
782 sbuf->count = nelems;
785 // Transformed pseudo code:
786 void alloc_buf(sized_buf_t *sbuf, sized_t nelems) {
787 // Materialize RHS values:
788 int *tmp_ptr = (int *)malloc(sizeof(int) * nelems);
789 int tmp_count = nelems;
791 // - checks to ensure that `lower <= tmp_ptr <= upper`
792 // - if (upper(tmp_ptr) - tmp_ptr < tmp_count) trap();
794 sbuf->count = tmp_count;
797 Whether the compiler can optimize such run-time checks depends on how the upper
798 bound of the pointer is derived. If the source pointer has ``__sized_by``,
799 ``__counted_by``, or a variant of such, the compiler assumes that the upper
800 bound calculation doesn't overflow, e.g., ``ptr + size`` (where the type of
801 ``ptr`` is ``void *__sized_by(size)``), because when the ``__sized_by`` pointer
802 is initialized, ``-fbounds-safety`` inserts run-time checks to ensure that ``ptr
803 + size`` doesn't overflow and that ``size >= 0``.
805 Assuming the upper bound calculation doesn't overflow, the compiler can simplify
806 the trap condition ``upper(tmp_ptr) - tmp_ptr < tmp_count`` to ``size <
807 tmp_count`` so if both ``size`` and ``tmp_count`` values are known at compile
808 time such that ``0 <= tmp_count <= size``, the optimizer can remove the check.
810 ``ptr + size`` may still overflow if the ``__sized_by`` pointer is created from
811 code that doesn't enable ``-fbounds-safety``, which is undefined behavior.
813 In the previous code example with the transformed ``alloc_buf()``, the upper
814 bound of ``tmp_ptr`` is derived from ``void *__sized_by_or_null(size)``, which
815 is the return type of ``malloc()``. Hence, the pointer arithmetic doesn't
816 overflow or ``tmp_ptr`` is null. Therefore, if ``nelems`` was given as a
817 compile-time constant, the compiler could remove the checks.
822 ``-fbounds-safety`` does not enforce overall type safety and bounds invariants
823 can still be violated by incorrect casts in some cases. That said,
824 ``-fbounds-safety`` prevents type conversions that change bounds attributes in a
825 way to violate the bounds invariant of the destination's pointer annotation.
826 Type conversions that change bounds attributes may be allowed if it does not
827 violate the invariant of the destination or that can be verified at run time.
828 Here are some of the important cast rules.
830 Two pointers that have different bounds annotations on their nested pointer
831 types are incompatible and cannot implicitly cast to each other. For example,
832 ``T *__single *__single`` cannot be converted to ``T *__bidi_indexable
833 *__single``. Such a conversion between incompatible nested bounds annotations
834 can be allowed using an explicit cast (e.g., C-style cast). Hereafter, the rules
835 only apply to the top pointer types. ``__unsafe_indexable`` cannot be converted
836 to any other safe pointer types (``__single``, ``__bidi_indexable``,
837 ``__counted_by``, etc) using a cast. The extension provides builtins to force
838 this conversion, ``__unsafe_forge_bidi_indexable(type, pointer, char_count)`` to
839 convert pointer to a ``__bidi_indexable`` pointer of type with ``char_count``
840 bytes available and ``__unsafe_forge_single(type, pointer)`` to convert pointer
841 to a single pointer of type type. The following examples show the usage of these
842 functions. Function ``example_forge_bidi()`` gets an external buffer from an
843 unsafe library by calling ``get_buf()`` which returns ``void
844 *__unsafe_indexable.`` Under the type rules, this cannot be directly assigned to
845 ``void *buf`` (implicitly ``void *__bidi_indexable``). Thus,
846 ``__unsafe_forge_bidi_indexable`` is used to manually create a
847 ``__bidi_indexable`` from the unsafe buffer.
852 void *__unsafe_indexable get_buf(void);
853 size_t get_buf_size(void);
855 // my_source1.c (enables -fbounds-safety)
856 #include "unsafe_library.h"
857 void example_forge_bidi(void) {
859 __unsafe_forge_bidi_indexable(void *, get_buf(), get_buf_size());
863 // my_source2.c (enables -fbounds-safety)
865 void example_forge_single(void) {
866 FILE *fp = __unsafe_forge_single(FILE *, fopen("mypath", "rb"));
870 * Function ``example_forge_single`` takes a file handle by calling fopen defined
871 in system header ``stdio.h``. Assuming ``stdio.h`` did not adopt
872 ``-fbounds-safety``, the return type of ``fopen`` would implicitly be ``FILE
873 *__unsafe_indexable`` and thus it cannot be directly assigned to ``FILE *fp``
874 in the bounds-safe source. To allow this operation, ``__unsafe_forge_single``
875 is used to create a ``__single`` from the return value of ``fopen``.
877 * Similar to ``__unsafe_indexable``, any non-pointer type (including ``int``,
878 ``intptr_t``, ``uintptr_t``, etc.) cannot be converted to any safe pointer
879 type because these don't have bounds information. ``__unsafe_forge_single`` or
880 ``__unsafe_forge_bidi_indexable`` must be used to force the conversion.
882 * Any safe pointer types can cast to ``__unsafe_indexable`` because it doesn't
883 have any invariant to maintain.
885 * ``__single`` casts to ``__bidi_indexable`` if the pointee type has a known
886 size. After the conversion, the resulting ``__bidi_indexable`` has the size of
887 a single object of the pointee type of ``__single``. ``__single`` cannot cast
888 to ``__bidi_indexable`` if the pointee type is incomplete or sizeless. For
889 example, ``void *__single`` cannot convert to ``void *__bidi_indexable``
890 because void is an incomplete type and thus the compiler cannot correctly
891 determine the upper bound of a single void pointer.
893 * Similarly, ``__single`` can cast to ``__indexable`` if the pointee type has a
894 known size. The resulting ``__indexable`` has the size of a single object of
897 * ``__single`` casts to ``__counted_by(E)`` only if ``E`` is 0 or 1.
899 * ``__single`` can cast to ``__single`` including when they have different
900 pointee types as long as it is allowed in the underlying C standard.
901 ``-fbounds-safety`` doesn't guarantee type safety.
903 * ``__bidi_indexable`` and ``__indexable`` can cast to ``__single``. The
904 compiler may insert run-time checks to ensure the pointer has at least a
905 single element or is a null pointer.
907 * ``__bidi_indexable`` casts to ``__indexable`` if the pointer does not have an
908 underflow. The compiler may insert run-time checks to ensure the pointer is
909 not below the lower bound.
911 * ``__indexable`` casts to ``__bidi_indexable``. The resulting
912 ``__bidi_indexable`` gets the lower bound same as the pointer value.
914 * A type conversion may involve both a bitcast and a bounds annotation cast. For
915 example, casting from ``int *__bidi_indexable`` to ``char *__single`` involve
916 a bitcast (``int *`` to ``char *``) and a bounds annotation cast
917 (``__bidi_indexable`` to ``__single``). In this case, the compiler performs
918 the bitcast and then converts the bounds annotation. This means, ``int
919 *__bidi_indexable`` will be converted to ``char *__bidi_indexable`` and then
920 to ``char *__single``.
922 * ``__terminated_by(T)`` cannot cast to any safe pointer type without the same
923 ``__terminated_by(T)`` attribute. To perform the cast, programmers can use an
924 intrinsic function such as ``__unsafe_terminated_by_to_indexable(P)`` to force
927 * ``__terminated_by(T)`` can cast to ``__unsafe_indexable``.
929 * Any type without ``__terminated_by(T)`` cannot cast to ``__terminated_by(T)``
930 without explicitly using an intrinsic function to allow it.
932 + ``__unsafe_terminated_by_from_indexable(T, PTR [, PTR_TO_TERM])`` casts any
933 safe pointer PTR to a ``__terminated_by(T)`` pointer. ``PTR_TO_TERM`` is an
934 optional argument where the programmer can provide the exact location of the
935 terminator. With this argument, the function can skip reading the entire
936 array in order to locate the end of the pointer (or the upper bound).
937 Providing an incorrect ``PTR_TO_TERM`` causes a run-time trap.
939 + ``__unsafe_forge_terminated_by(T, P, E)`` creates ``T __terminated_by(E)``
940 pointer given any pointer ``P``. Tmust be a pointer type.
942 Portability with toolchains that do not support the extension
943 -------------------------------------------------------------
945 The language model is designed so that it doesn't alter the semantics of the
946 original C program, other than introducing deterministic traps where otherwise
947 the behavior is undefined and/or unsafe. Clang provides a toolchain header
948 (``ptrcheck.h``) that macro-defines the annotations as type attributes when
949 ``-fbounds-safety`` is enabled and defines them to empty when the extension is
950 disabled. Thus, the code adopting ``-fbounds-safety`` can compile with
951 toolchains that do not support this extension, by including the header or adding
952 macros to define the annotations to empty. For example, the toolchain not
953 supporting this extension may not have a header defining ``__counted_by``, so
954 the code using ``__counted_by`` must define it as nothing or include a header
959 #if defined(__has_feature) && __has_feature(bounds_safety)
960 #define __counted_by(T) __attribute__((__counted_by__(T)))
961 // ... other bounds annotations
962 #else #define __counted_by(T) // defined as nothing
963 // ... other bounds annotations
966 // expands to `void foo(int * ptr, size_t count);`
967 // when extension is not enabled or not available
968 void foo(int *__counted_by(count) ptr, size_t count);
970 Other potential applications of bounds annotations
971 ==================================================
973 The bounds annotations provided by the ``-fbounds-safety`` programming model
974 have potential use cases beyond the language extension itself. For example,
975 static and dynamic analysis tools could use the bounds information to improve
976 diagnostics for out-of-bounds accesses, even if ``-fbounds-safety`` is not used.
977 The bounds annotations could be used to improve C interoperability with
978 bounds-safe languages, providing a better mapping to bounds-safe types in the
979 safe language interface. The bounds annotations can also serve as documentation
980 specifying the relationship between declarations.
985 ``-fbounds-safety`` aims to bring the bounds safety guarantee to the C language,
986 and it does not guarantee other types of memory safety properties. Consequently,
987 it may not prevent some of the secondary bounds safety violations caused by
988 other types of safety violations such as type confusion. For instance,
989 ``-fbounds-safety`` does not perform type-safety checks on conversions between
990 `__single`` pointers of different pointee types (e.g., ``char *__single`` →
991 ``void *__single`` → ``int *__single``) beyond what the foundation languages
992 (C/C++) already offer.
994 ``-fbounds-safety`` heavily relies on run-time checks to keep the bounds safety
995 and the soundness of the type system. This may incur significant code size
996 overhead in unoptimized builds and leaving some of the adoption mistakes to be
997 caught only at run time. This is not a fundamental limitation, however, because
998 incrementally adding necessary static analysis will allow us to catch issues
999 early on and remove unnecessary bounds checks in unoptimized builds.