From 0744fa4f533c765d0a704fe8aa7174a0f93eb7bc Mon Sep 17 00:00:00 2001 From: Nicolas Iooss Date: Thu, 22 Apr 2021 08:46:04 +0200 Subject: [PATCH] libsepol: use checked arithmetic builtin to perform safe addition Checking whether an overflow occurred after adding two values can be achieved using checked arithmetic builtin functions such as: bool __builtin_add_overflow(type1 x, type2 y, type3 *sum); This function is available at least in clang (at least since clang 3.8.0, https://releases.llvm.org/3.8.0/tools/clang/docs/LanguageExtensions.html#checked-arithmetic-builtins) and gcc (https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html, since gcc 5 according to https://gcc.gnu.org/gcc-5/changes.html) Signed-off-by: Nicolas Iooss --- libsepol/src/context_record.c | 29 ++++++----------------------- libsepol/src/module_to_cil.c | 6 ++---- 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/libsepol/src/context_record.c b/libsepol/src/context_record.c index 317a42133884..435f788058c4 100644 --- a/libsepol/src/context_record.c +++ b/libsepol/src/context_record.c @@ -267,31 +267,13 @@ int sepol_context_from_string(sepol_handle_t * handle, return STATUS_ERR; } - -static inline int safe_sum(size_t *sum, const size_t augends[], const size_t cnt) { - - size_t a, i; - - *sum = 0; - for(i=0; i < cnt; i++) { - /* sum should not be smaller than the addend */ - a = augends[i]; - *sum += a; - if (*sum < a) { - return i; - } - } - - return 0; -} - int sepol_context_to_string(sepol_handle_t * handle, const sepol_context_t * con, char **str_ptr) { int rc; char *str = NULL; - size_t total_sz, err; + size_t total_sz = 0, i; const size_t sizes[] = { strlen(con->user), /* user length */ strlen(con->role), /* role length */ @@ -300,10 +282,11 @@ int sepol_context_to_string(sepol_handle_t * handle, ((con->mls) ? 3 : 2) + 1 /* mls has extra ":" also null byte */ }; - err = safe_sum(&total_sz, sizes, ARRAY_SIZE(sizes)); - if (err) { - ERR(handle, "invalid size, overflow at position: %zu", err); - goto err; + for (i = 0; i < ARRAY_SIZE(sizes); i++) { + if (__builtin_add_overflow(total_sz, sizes[i], &total_sz)) { + ERR(handle, "invalid size, overflow at position: %zu", i); + goto err; + } } str = (char *)malloc(total_sz); diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c index 58df0d4f6d77..496693f4616e 100644 --- a/libsepol/src/module_to_cil.c +++ b/libsepol/src/module_to_cil.c @@ -1134,16 +1134,14 @@ static int name_list_to_string(char **names, unsigned int num_names, char **stri char *strpos; for (i = 0; i < num_names; i++) { - len += strlen(names[i]); - if (len < strlen(names[i])) { + if (__builtin_add_overflow(len, strlen(names[i]), &len)) { log_err("Overflow"); return -1; } } // add spaces + null terminator - len += num_names; - if (len < (size_t)num_names) { + if (__builtin_add_overflow(len, (size_t)num_names, &len)) { log_err("Overflow"); return -1; } -- 2.32.0