.. | .. |
---|
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 */ |
---|