| .. | .. |
|---|
| 44 | 44 | #define is_non_negative(a) ((a) > 0 || (a) == 0) |
|---|
| 45 | 45 | #define is_negative(a) (!(is_non_negative(a))) |
|---|
| 46 | 46 | |
|---|
| 47 | +/* |
|---|
| 48 | + * Allows for effectively applying __must_check to a macro so we can have |
|---|
| 49 | + * both the type-agnostic benefits of the macros while also being able to |
|---|
| 50 | + * enforce that the return value is, in fact, checked. |
|---|
| 51 | + */ |
|---|
| 52 | +static inline bool __must_check __must_check_overflow(bool overflow) |
|---|
| 53 | +{ |
|---|
| 54 | + return unlikely(overflow); |
|---|
| 55 | +} |
|---|
| 56 | + |
|---|
| 47 | 57 | #ifdef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW |
|---|
| 48 | 58 | /* |
|---|
| 49 | 59 | * For simplicity and code hygiene, the fallback code below insists on |
|---|
| .. | .. |
|---|
| 53 | 63 | * alias for __builtin_add_overflow, but add type checks similar to |
|---|
| 54 | 64 | * below. |
|---|
| 55 | 65 | */ |
|---|
| 56 | | -#define check_add_overflow(a, b, d) ({ \ |
|---|
| 66 | +#define check_add_overflow(a, b, d) __must_check_overflow(({ \ |
|---|
| 57 | 67 | typeof(a) __a = (a); \ |
|---|
| 58 | 68 | typeof(b) __b = (b); \ |
|---|
| 59 | 69 | typeof(d) __d = (d); \ |
|---|
| 60 | 70 | (void) (&__a == &__b); \ |
|---|
| 61 | 71 | (void) (&__a == __d); \ |
|---|
| 62 | 72 | __builtin_add_overflow(__a, __b, __d); \ |
|---|
| 63 | | -}) |
|---|
| 73 | +})) |
|---|
| 64 | 74 | |
|---|
| 65 | | -#define check_sub_overflow(a, b, d) ({ \ |
|---|
| 75 | +#define check_sub_overflow(a, b, d) __must_check_overflow(({ \ |
|---|
| 66 | 76 | typeof(a) __a = (a); \ |
|---|
| 67 | 77 | typeof(b) __b = (b); \ |
|---|
| 68 | 78 | typeof(d) __d = (d); \ |
|---|
| 69 | 79 | (void) (&__a == &__b); \ |
|---|
| 70 | 80 | (void) (&__a == __d); \ |
|---|
| 71 | 81 | __builtin_sub_overflow(__a, __b, __d); \ |
|---|
| 72 | | -}) |
|---|
| 82 | +})) |
|---|
| 73 | 83 | |
|---|
| 74 | | -#define check_mul_overflow(a, b, d) ({ \ |
|---|
| 84 | +#define check_mul_overflow(a, b, d) __must_check_overflow(({ \ |
|---|
| 75 | 85 | typeof(a) __a = (a); \ |
|---|
| 76 | 86 | typeof(b) __b = (b); \ |
|---|
| 77 | 87 | typeof(d) __d = (d); \ |
|---|
| 78 | 88 | (void) (&__a == &__b); \ |
|---|
| 79 | 89 | (void) (&__a == __d); \ |
|---|
| 80 | 90 | __builtin_mul_overflow(__a, __b, __d); \ |
|---|
| 81 | | -}) |
|---|
| 91 | +})) |
|---|
| 82 | 92 | |
|---|
| 83 | 93 | #else |
|---|
| 84 | 94 | |
|---|
| .. | .. |
|---|
| 191 | 201 | }) |
|---|
| 192 | 202 | |
|---|
| 193 | 203 | |
|---|
| 194 | | -#define check_add_overflow(a, b, d) \ |
|---|
| 204 | +#define check_add_overflow(a, b, d) __must_check_overflow( \ |
|---|
| 195 | 205 | __builtin_choose_expr(is_signed_type(typeof(a)), \ |
|---|
| 196 | 206 | __signed_add_overflow(a, b, d), \ |
|---|
| 197 | | - __unsigned_add_overflow(a, b, d)) |
|---|
| 207 | + __unsigned_add_overflow(a, b, d))) |
|---|
| 198 | 208 | |
|---|
| 199 | | -#define check_sub_overflow(a, b, d) \ |
|---|
| 209 | +#define check_sub_overflow(a, b, d) __must_check_overflow( \ |
|---|
| 200 | 210 | __builtin_choose_expr(is_signed_type(typeof(a)), \ |
|---|
| 201 | 211 | __signed_sub_overflow(a, b, d), \ |
|---|
| 202 | | - __unsigned_sub_overflow(a, b, d)) |
|---|
| 212 | + __unsigned_sub_overflow(a, b, d))) |
|---|
| 203 | 213 | |
|---|
| 204 | | -#define check_mul_overflow(a, b, d) \ |
|---|
| 214 | +#define check_mul_overflow(a, b, d) __must_check_overflow( \ |
|---|
| 205 | 215 | __builtin_choose_expr(is_signed_type(typeof(a)), \ |
|---|
| 206 | 216 | __signed_mul_overflow(a, b, d), \ |
|---|
| 207 | | - __unsigned_mul_overflow(a, b, d)) |
|---|
| 208 | | - |
|---|
| 217 | + __unsigned_mul_overflow(a, b, d))) |
|---|
| 209 | 218 | |
|---|
| 210 | 219 | #endif /* COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW */ |
|---|
| 211 | 220 | |
|---|
| .. | .. |
|---|
| 228 | 237 | * '*d' will hold the results of the attempted shift, but is not |
|---|
| 229 | 238 | * considered "safe for use" if false is returned. |
|---|
| 230 | 239 | */ |
|---|
| 231 | | -#define check_shl_overflow(a, s, d) ({ \ |
|---|
| 240 | +#define check_shl_overflow(a, s, d) __must_check_overflow(({ \ |
|---|
| 232 | 241 | typeof(a) _a = a; \ |
|---|
| 233 | 242 | typeof(s) _s = s; \ |
|---|
| 234 | 243 | typeof(d) _d = d; \ |
|---|
| .. | .. |
|---|
| 238 | 247 | *_d = (_a_full << _to_shift); \ |
|---|
| 239 | 248 | (_to_shift != _s || is_negative(*_d) || is_negative(_a) || \ |
|---|
| 240 | 249 | (*_d >> _to_shift) != _a); \ |
|---|
| 241 | | -}) |
|---|
| 250 | +})) |
|---|
| 242 | 251 | |
|---|
| 243 | 252 | /** |
|---|
| 244 | 253 | * array_size() - Calculate size of 2-dimensional array. |
|---|
| .. | .. |
|---|
| 285 | 294 | return bytes; |
|---|
| 286 | 295 | } |
|---|
| 287 | 296 | |
|---|
| 288 | | -static inline __must_check size_t __ab_c_size(size_t n, size_t size, size_t c) |
|---|
| 297 | +/* |
|---|
| 298 | + * Compute a*b+c, returning SIZE_MAX on overflow. Internal helper for |
|---|
| 299 | + * struct_size() below. |
|---|
| 300 | + */ |
|---|
| 301 | +static inline __must_check size_t __ab_c_size(size_t a, size_t b, size_t c) |
|---|
| 289 | 302 | { |
|---|
| 290 | 303 | size_t bytes; |
|---|
| 291 | 304 | |
|---|
| 292 | | - if (check_mul_overflow(n, size, &bytes)) |
|---|
| 305 | + if (check_mul_overflow(a, b, &bytes)) |
|---|
| 293 | 306 | return SIZE_MAX; |
|---|
| 294 | 307 | if (check_add_overflow(bytes, c, &bytes)) |
|---|
| 295 | 308 | return SIZE_MAX; |
|---|
| .. | .. |
|---|
| 301 | 314 | * struct_size() - Calculate size of structure with trailing array. |
|---|
| 302 | 315 | * @p: Pointer to the structure. |
|---|
| 303 | 316 | * @member: Name of the array member. |
|---|
| 304 | | - * @n: Number of elements in the array. |
|---|
| 317 | + * @count: Number of elements in the array. |
|---|
| 305 | 318 | * |
|---|
| 306 | 319 | * Calculates size of memory needed for structure @p followed by an |
|---|
| 307 | | - * array of @n @member elements. |
|---|
| 320 | + * array of @count number of @member elements. |
|---|
| 308 | 321 | * |
|---|
| 309 | 322 | * Return: number of bytes needed or SIZE_MAX on overflow. |
|---|
| 310 | 323 | */ |
|---|
| 311 | | -#define struct_size(p, member, n) \ |
|---|
| 312 | | - __ab_c_size(n, \ |
|---|
| 324 | +#define struct_size(p, member, count) \ |
|---|
| 325 | + __ab_c_size(count, \ |
|---|
| 313 | 326 | sizeof(*(p)->member) + __must_be_array((p)->member),\ |
|---|
| 314 | 327 | sizeof(*(p))) |
|---|
| 315 | 328 | |
|---|
| 329 | +/** |
|---|
| 330 | + * flex_array_size() - Calculate size of a flexible array member |
|---|
| 331 | + * within an enclosing structure. |
|---|
| 332 | + * |
|---|
| 333 | + * @p: Pointer to the structure. |
|---|
| 334 | + * @member: Name of the flexible array member. |
|---|
| 335 | + * @count: Number of elements in the array. |
|---|
| 336 | + * |
|---|
| 337 | + * Calculates size of a flexible array of @count number of @member |
|---|
| 338 | + * elements, at the end of structure @p. |
|---|
| 339 | + * |
|---|
| 340 | + * Return: number of bytes needed or SIZE_MAX on overflow. |
|---|
| 341 | + */ |
|---|
| 342 | +#define flex_array_size(p, member, count) \ |
|---|
| 343 | + array_size(count, \ |
|---|
| 344 | + sizeof(*(p)->member) + __must_be_array((p)->member)) |
|---|
| 345 | + |
|---|
| 316 | 346 | #endif /* __LINUX_OVERFLOW_H */ |
|---|