diff options
| author | jvoisin | 2023-07-09 18:12:01 +0200 |
|---|---|---|
| committer | jvoisin | 2023-07-09 18:15:35 +0200 |
| commit | a37c769fbbc956461210317fa856be4042c144f4 (patch) | |
| tree | 80c335085b82e6f6ff52101c070f0e3e74119443 | |
| parent | f9f83da31803062d1fb665ad612ccede5e445757 (diff) | |
Improve a bit `size_t*size_t` overflow checks
| -rw-r--r-- | include/fortify-headers.h | 21 | ||||
| -rw-r--r-- | include/stdio.h | 4 |
2 files changed, 23 insertions, 2 deletions
diff --git a/include/fortify-headers.h b/include/fortify-headers.h index 6ab5e74..065bca2 100644 --- a/include/fortify-headers.h +++ b/include/fortify-headers.h | |||
| @@ -45,6 +45,10 @@ | |||
| 45 | 45 | ||
| 46 | /* Use __builtin_dynamic_object_size with _FORTIFY_SOURCE>2, if available. */ | 46 | /* Use __builtin_dynamic_object_size with _FORTIFY_SOURCE>2, if available. */ |
| 47 | #if _FORTIFY_SOURCE > 2 && defined __has_builtin && __has_builtin (__builtin_dynamic_object_size) | 47 | #if _FORTIFY_SOURCE > 2 && defined __has_builtin && __has_builtin (__builtin_dynamic_object_size) |
| 48 | /* | ||
| 49 | * See: | ||
| 50 | * - https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html | ||
| 51 | */ | ||
| 48 | #define __bos(ptr, type) __builtin_dynamic_object_size (ptr, type) | 52 | #define __bos(ptr, type) __builtin_dynamic_object_size (ptr, type) |
| 49 | #else | 53 | #else |
| 50 | #define __bos(ptr, type) __builtin_object_size (ptr, type) | 54 | #define __bos(ptr, type) __builtin_object_size (ptr, type) |
| @@ -57,3 +61,20 @@ | |||
| 57 | #endif | 61 | #endif |
| 58 | 62 | ||
| 59 | #endif | 63 | #endif |
| 64 | |||
| 65 | |||
| 66 | /* TODO(jvoisin) Figure a nice way to make use of __builtin_mul_overflow while ignoring the result. */ | ||
| 67 | /* TODO(jvoisin) Make use of C23's stdckdint header: https://gustedt.gitlabpages.inria.fr/c23-library/#stdckdint */ | ||
| 68 | #if _FORTIFY_SOURCE > 2 && defined __has_builtin | ||
| 69 | /* | ||
| 70 | * See: | ||
| 71 | * - https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html | ||
| 72 | * - https://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins | ||
| 73 | */ | ||
| 74 | #if __has_builtin (__builtin_mul_overflow_p) | ||
| 75 | #define __bmo(x, y) (x != 0 && __builtin_mul_overflow_p(x, y, (__typeof__ ((x) + (y))) 0)) | ||
| 76 | #else /* !__builtin_mul_overflow_p */ | ||
| 77 | #define __bmo(x, y) (x != 0 && (x * y) / x != y) | ||
| 78 | #endif /* __builtin_mul_overflow_p */ | ||
| 79 | |||
| 80 | #endif /* __has_builtin */ | ||
diff --git a/include/stdio.h b/include/stdio.h index cc16e46..d5206f5 100644 --- a/include/stdio.h +++ b/include/stdio.h | |||
| @@ -53,7 +53,7 @@ _FORTIFY_FN(fread) size_t fread(void * _FORTIFY_POS0 __d, size_t __n, | |||
| 53 | { | 53 | { |
| 54 | size_t __b = __bos(__d, 0); | 54 | size_t __b = __bos(__d, 0); |
| 55 | 55 | ||
| 56 | if (__n != 0 && (__n * __m) / __n != __m) | 56 | if (__bmo(__n, __m)) |
| 57 | __builtin_trap(); | 57 | __builtin_trap(); |
| 58 | if (__n * __m > __b) | 58 | if (__n * __m > __b) |
| 59 | __builtin_trap(); | 59 | __builtin_trap(); |
| @@ -66,7 +66,7 @@ _FORTIFY_FN(fwrite) size_t fwrite(const void * _FORTIFY_POS0 __d, size_t __n, | |||
| 66 | { | 66 | { |
| 67 | size_t __b = __bos(__d, 0); | 67 | size_t __b = __bos(__d, 0); |
| 68 | 68 | ||
| 69 | if (__n != 0 && (__n * __m) / __n != __m) | 69 | if (__bmo(__n, __m)) |
| 70 | __builtin_trap(); | 70 | __builtin_trap(); |
| 71 | if (__n * __m > __b) | 71 | if (__n * __m > __b) |
| 72 | __builtin_trap(); | 72 | __builtin_trap(); |
