1 /*===---- ptrcheck.h - Pointer bounds hints & specifications ----------------=== 2 * 3 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 * See https://llvm.org/LICENSE.txt for license information. 5 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 * 7 *===-----------------------------------------------------------------------=== 8 */ 9 10 #ifndef __PTRCHECK_H 11 #define __PTRCHECK_H 12 13 /* __has_ptrcheck can be used in preprocessor macros (and other parts of the 14 language expecting constant expressions) to test if bounds attributes 15 exist. */ 16 #if defined(__has_feature) && __has_feature(bounds_attributes) 17 #define __has_ptrcheck 1 18 #else 19 #define __has_ptrcheck 0 20 #endif 21 22 #if __has_ptrcheck 23 24 /* An attribute that modifies a pointer type such that its ABI is three pointer 25 components: the pointer value itself (the pointer value); one-past-the-end of 26 the object it is derived from (the upper bound); and the base address of the 27 object it is derived from (the lower bound). The pointer value is allowed to 28 lie outside the [lower bound, upper bound) interval, and it supports the 29 entire range of arithmetic operations that are usually applicable to 30 pointers. Bounds are implicitly checked only when the pointer is dereferenced 31 or converted to a different representation. */ 32 #define __bidi_indexable __attribute__((__bidi_indexable__)) 33 34 /* An attribute that modifies a pointer type such that its ABI is two pointer 35 components: the pointer value itself (the lower bound); and one-past-the-end 36 of the object it is derived from (the upper bound). Indexable pointers do not 37 support negative arithmetic operations: it is a compile-time error to use a 38 subtraction or add a negative quantity to them, and it is a runtime error if 39 the same happens at runtime while it can't be detected at compile-time. Same 40 as __bidi_indexable pointers, __indexable pointers are bounds-checked when 41 dereferenced or converted to another representation. */ 42 #define __indexable __attribute__((__indexable__)) 43 44 /* An attribute that modifies a pointer type such than it has the ABI of a 45 regular C pointer, without allowing pointer arithmetic. Pointer arithmetic is 46 a compile-time error. A __single pointer is expected to be either NULL or 47 point to exactly one valid value. */ 48 #define __single __attribute__((__single__)) 49 50 /* An attribute that modifies a pointer type such than it can be used exactly 51 like a regular C pointer, with unchecked arithmetic and dereferencing. An 52 __unsafe_indexable pointer cannot convert implicitly to another type of 53 pointer since that would require information that is not available to the 54 program. You must use __unsafe_forge_bidi_indexable or __unsafe_forge_single 55 to convert __unsafe_indexable pointers to so-called safe pointers. */ 56 #define __unsafe_indexable __attribute__((__unsafe_indexable__)) 57 58 /* An attribute that modifies a pointer type such that it has the ABI of a 59 regular C pointer, but it implicitly converts to a __bidi_indexable pointer 60 with bounds that assume there are N valid elements starting at its address. 61 The conversion happens at the same point the object converts to an rvalue, or 62 immediately for values which cannot be lvalues (such as function calls). */ 63 64 /* Assignments to the pointer object must be accompanied with an assignment to 65 N if it is assignable. */ 66 67 /* N must either be an expression that evaluates to a constant, or an integer 68 declaration from the same scope, or (for structure fields) a declaration 69 contained in basic arithmetic. */ 70 #define __counted_by(N) __attribute__((__counted_by__(N))) 71 72 /* Identical to __counted_by(N), aside that N is a byte count instead of an 73 object count. */ 74 #define __sized_by(N) __attribute__((__sized_by__(N))) 75 76 /* An attribute that modifies a pointer type such that it has the ABI of a 77 regular C pointer, but it implicitly converts to a __bidi_indexable pointer 78 with bounds that assume that E is one-past-the-end of the original object. 79 Implicitly, referencing E in the same scope will create a pointer that 80 converts to a __bidi_indexable pointer one-past-the-end of the original 81 object, but with a lower bound set to the value of the pointer that is 82 attributed. */ 83 84 /* Assignments to the pointer object must be accompanied with an assignment to 85 E if it is assignable. */ 86 #define __ended_by(E) __attribute__((__ended_by__(E))) 87 88 /* The __terminated_by(T) attribute can be applied to arrays and pointers. The 89 argument T specifies the terminator and must be an integer constant 90 expression. Even though T has to be an integer constant, __terminated_by(T) 91 can be applied to pointer arrays as well. For convenience, the 92 __null_terminated macro is provided, which is equivalent to 93 __terminated_by(0). 94 95 The __terminated_by(T) attribute can be applied only to __single pointers. If 96 the pointer attribute is not specified, it is automatically set to __single. 97 A __terminated_by(T) pointer points to the first element of an array that is 98 terminated with T. 99 100 Arithmetic on __terminated_by(T) pointers is restricted to only incrementing 101 the pointer by one, and must be able to be evaluated at compile-time. 102 Pointer arithmetic generates a runtime check to ensure that the pointer 103 doesn't point pass the terminator. 104 105 A __terminated_by(T) pointer has the ABI of a regular C pointer. 106 107 When __terminated_by(T) is applied to an array, the compiler checks if the 108 array is terminated with the given terminator T during the initialization. 109 Moreover, a __terminated_by(T) array decays to a __terminated_by(T) __single 110 pointer, instead of decaying to a __bidi_indexable pointer. */ 111 #define __terminated_by(T) __attribute__((__terminated_by__(T))) 112 #define __null_terminated __terminated_by(0) 113 114 /* Directives that tells the compiler to assume that subsequent pointer types 115 have the ABI specified by the ABI parameter, which may be one of single, 116 indexable, bidi_indexable or unsafe_indexable. */ 117 118 /* In project files, the ABI is assumed to be single by default. In headers 119 included from libraries or the SDK, the ABI is assumed to be unsafe_indexable 120 by default. */ 121 #define __ptrcheck_abi_assume_single() \ 122 _Pragma("clang abi_ptr_attr set(single)") 123 124 #define __ptrcheck_abi_assume_indexable() \ 125 _Pragma("clang abi_ptr_attr set(indexable)") 126 127 #define __ptrcheck_abi_assume_bidi_indexable() \ 128 _Pragma("clang abi_ptr_attr set(bidi_indexable)") 129 130 #define __ptrcheck_abi_assume_unsafe_indexable() \ 131 _Pragma("clang abi_ptr_attr set(unsafe_indexable)") 132 133 /* Create a __bidi_indexable pointer of a given pointer type (T), starting at 134 address P, pointing to S bytes of valid memory. T must be a pointer type. */ 135 #define __unsafe_forge_bidi_indexable(T, P, S) \ 136 ((T __bidi_indexable)__builtin_unsafe_forge_bidi_indexable((P), (S))) 137 138 /* Create a __single pointer of a given type (T), starting at address P. T must 139 be a pointer type. */ 140 #define __unsafe_forge_single(T, P) \ 141 ((T __single)__builtin_unsafe_forge_single((P))) 142 143 /* Create a __terminated_by pointer of a given pointer type (T), starting at 144 address P, terminated by E. T must be a pointer type. */ 145 #define __unsafe_forge_terminated_by(T, P, E) \ 146 ((T __terminated_by(E))__builtin_unsafe_forge_terminated_by((P), (E))) 147 148 /* Create a __terminated_by pointer of a given pointer type (T), starting at 149 address P, terminated by 0. T must be a pointer type. */ 150 #define __unsafe_forge_null_terminated(T, P) __unsafe_forge_terminated_by(T, P, 0) 151 152 /* Create a wide pointer with the same lower bound and upper bounds as X, but 153 with a pointer component also equal to the lower bound. */ 154 #define __ptr_lower_bound(X) __builtin_get_pointer_lower_bound(X) 155 156 /* Create a wide pointer with the same lower bound and upper bounds as X, but 157 with a pointer component also equal to the upper bound. */ 158 #define __ptr_upper_bound(X) __builtin_get_pointer_upper_bound(X) 159 160 /* Convert a __terminated_by(T) pointer to an __indexable pointer. These 161 operations will calculate the upper bound by iterating over the memory 162 pointed to by P in order to find the terminator. 163 164 The __terminated_by_to_indexable(P) does NOT include the terminator within 165 bounds of the __indexable pointer. Consequently, the terminator cannot be 166 erased (or even accessed) through the __indexable pointer. The address one 167 past the end of the array (pointing to the terminator) can be found with 168 __ptr_upper_bound(). 169 170 The __unsafe_terminated_by_to_indexable(P) does include the terminator within 171 the bounds of the __indexable pointer. This makes the operation unsafe, since 172 the terminator can be erased, and thus using P might result in out-of-bounds 173 access. */ 174 #define __terminated_by_to_indexable(P) \ 175 __builtin_terminated_by_to_indexable(P) 176 #define __unsafe_terminated_by_to_indexable(P) \ 177 __builtin_unsafe_terminated_by_to_indexable(P) 178 179 #define __null_terminated_to_indexable(P) \ 180 ({ \ 181 __typeof__(*(P)) *__null_terminated __ptr = (P); \ 182 __terminated_by_to_indexable(__ptr); \ 183 }) 184 185 #define __unsafe_null_terminated_to_indexable(P) \ 186 ({ \ 187 __typeof__(*(P)) *__null_terminated __ptr = (P); \ 188 __unsafe_terminated_by_to_indexable(__ptr); \ 189 }) 190 191 /* __unsafe_terminated_by_from_indexable(T, PTR [, PTR_TO_TERM]) converts an 192 __indexable pointer to a __terminated_by(T) pointer. The operation will 193 check if the given terminator T occurs in the memory pointed to by PTR. 194 If so, the operation evaluates to __terminated_by(T) pointer. Otherwise, it 195 traps. 196 197 The operation has an optional parameter PTR_TO_TERM, which changes the way 198 how the check for the terminator existence is generated. PTR_TO_TERM must 199 point to the terminator element and be within the bounds of PTR. 200 If PTR_TO_TERM is provided, the runtime will check if it is in fact within 201 the bounds and points to an element that equals to T. If PTR_TO_TERM is not 202 provided, the runtime will iterate over the memory pointed to by PTR to find 203 the terminator. 204 205 The operation is unsafe, since the terminator can be erased through PTR after 206 the conversion. This can result in out-of-bounds access through the newly 207 created __terminated_by(T) pointer. 208 209 For convenience, the 210 __unsafe_null_terminated_from_indexable(PTR [, PTR_TO_TERM]) macro is 211 provided, which assumes that the terminator is 0. */ 212 #define __unsafe_terminated_by_from_indexable(T, ...) \ 213 __builtin_unsafe_terminated_by_from_indexable((T), __VA_ARGS__) 214 #define __unsafe_null_terminated_from_indexable(...) \ 215 __builtin_unsafe_terminated_by_from_indexable(0, __VA_ARGS__) 216 217 /* Instruct the compiler to disregard the bounds of an array used in a function 218 prototype and allow the decayed pointer to use __counted_by. This is a niche 219 capability that is only useful in limited patterns (the way that `mig` uses 220 arrays being one of them). */ 221 #define __array_decay_dicards_count_in_parameters \ 222 __attribute__((__decay_discards_count_in_parameters__)) 223 224 /* An attribute to indicate a variable to be effectively constant (or data const) 225 that it is allocated in a const section so cannot be modified after an early 226 stage of bootup, for example. Adding this attribute allows a global variable 227 to be used in __counted_by attribute of struct fields, function parameter, or 228 local variable just like actual constants. 229 Note that ensuring the value never changes once it is used is the user's 230 responsibility. One way to achieve this is the xnu model, in which certain 231 variables are placed in a segment that is remapped as read-only after 232 initialization. */ 233 #define __unsafe_late_const __attribute__((__unsafe_late_const__)) 234 235 /* An attribute to indicate that a function is unavailable when -fbounds-safety 236 is enabled because it is unsafe. Calls to functions annotated with this 237 attribute are errors when -fbounds-safety is enabled, but are allowed when 238 -fbounds-safety is disabled. 239 240 Example: 241 242 void* __ptrcheck_unavailable some_unsafe_api(void*); 243 */ 244 #define __ptrcheck_unavailable \ 245 __attribute__((__unavailable__("unavailable with -fbounds-safety."))) 246 247 /* __ptrcheck_unavailable_r is the same as __ptrcheck_unavailable but it takes 248 as an argument the name of replacement function that is safe for use with 249 -fbounds-safety enabled. 250 251 Example: 252 253 void* __counted_by(size) safe_api(void* __counted_by(size), size_t size); 254 255 void* __ptrcheck_unavailable_r(safe_api) some_unsafe_api(void*); 256 */ 257 #define __ptrcheck_unavailable_r(REPLACEMENT) \ 258 __attribute__((__unavailable__( \ 259 "unavailable with -fbounds-safety. Use " #REPLACEMENT " instead."))) 260 261 #else 262 263 /* We intentionally define to nothing pointer attributes which do not have an 264 impact on the ABI. __indexable and __bidi_indexable are not defined because 265 of the ABI incompatibility that makes the diagnostic preferable. */ 266 #define __single 267 #define __unsafe_indexable 268 #define __counted_by(N) 269 #define __sized_by(N) 270 #define __ended_by(E) 271 272 /* We intentionally define the terminated_by attributes to nothing. */ 273 #define __terminated_by(T) 274 #define __null_terminated 275 276 /* Similarly, we intentionally define to nothing the 277 __ptrcheck_abi_assume_single and __ptrcheck_abi_assume_unsafe_indexable 278 macros because they do not lead to an ABI incompatibility. However, we do not 279 define the indexable and unsafe_indexable ones because the diagnostic is 280 better than the silent ABI break. */ 281 #define __ptrcheck_abi_assume_single() 282 #define __ptrcheck_abi_assume_unsafe_indexable() 283 284 /* __unsafe_forge intrinsics are defined as regular C casts. */ 285 #define __unsafe_forge_bidi_indexable(T, P, S) ((T)(P)) 286 #define __unsafe_forge_single(T, P) ((T)(P)) 287 #define __unsafe_forge_terminated_by(T, P, E) ((T)(P)) 288 #define __unsafe_forge_null_terminated(T, P) ((T)(P)) 289 290 /* The conversion between terminated_by pointers just evaluates to the pointer 291 argument. */ 292 #define __terminated_by_to_indexable(P) (P) 293 #define __unsafe_terminated_by_to_indexable(P) (P) 294 #define __null_terminated_to_indexable(P) (P) 295 #define __unsafe_null_terminated_to_indexable(P) (P) 296 #define __unsafe_terminated_by_from_indexable(T, P, ...) (P) 297 #define __unsafe_null_terminated_from_indexable(P, ...) (P) 298 299 /* decay operates normally; attribute is meaningless without pointer checks. */ 300 #define __array_decay_dicards_count_in_parameters 301 302 #define __ptrcheck_unavailable 303 #define __ptrcheck_unavailable_r(R) 304 305 #endif /* __has_ptrcheck */ 306 307 #endif /* __PTRCHECK_H */ 308