mirror of
https://git.kernel.org/pub/scm/utils/kernel/kmod/kmod.git
synced 2024-12-05 09:43:46 +08:00
shared: add helper function to add and check for overflow
Use _builtin_uaddll_overflow/_builtin_uaddl_overflow when available,
abstracting the type to use it with uint64_t.
Otherwise fallback to the implementation as added in 67466f2
("Prevent
offset + size overflow.").
This also adds the tests for this new helper in the testsuite.
This commit is contained in:
parent
14c3244f04
commit
aac5f4514f
@ -49,6 +49,8 @@ AC_CHECK_FUNCS_ONCE([finit_module])
|
||||
|
||||
CC_CHECK_FUNC_BUILTIN([__builtin_clz])
|
||||
CC_CHECK_FUNC_BUILTIN([__builtin_types_compatible_p])
|
||||
CC_CHECK_FUNC_BUILTIN([__builtin_uaddl_overflow], [ ], [ ])
|
||||
CC_CHECK_FUNC_BUILTIN([__builtin_uaddll_overflow], [ ], [ ])
|
||||
|
||||
# dietlibc doesn't have st.st_mtim struct member
|
||||
AC_CHECK_MEMBERS([struct stat.st_mtim], [], [], [#include <sys/stat.h>])
|
||||
|
@ -262,6 +262,8 @@ AC_DEFUN([CC_CHECK_FUNC_BUILTIN], [
|
||||
m4_case([$1],
|
||||
[__builtin_clz], [$1(0)],
|
||||
[__builtin_types_compatible_p], [$1(int, int)],
|
||||
[__builtin_uaddl_overflow], [$1(0UL, 0UL, (void*)0)],
|
||||
[__builtin_uaddll_overflow], [$1(0ULL, 0ULL, (void*)0)],
|
||||
[__builtin_expect], [$1(0, 0)]
|
||||
)])],
|
||||
[cc_cv_have_$1=yes],
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
@ -72,3 +73,18 @@ static inline void freep(void *p) {
|
||||
free(*(void**) p);
|
||||
}
|
||||
#define _cleanup_free_ _cleanup_(freep)
|
||||
|
||||
static inline bool addu64_overflow(uint64_t a, uint64_t b, uint64_t *res)
|
||||
{
|
||||
#if (HAVE___BUILTIN_UADDL_OVERFLOW && HAVE___BUILTIN_UADDLL_OVERFLOW)
|
||||
#if __SIZEOF_LONG__ == 8
|
||||
return __builtin_uaddl_overflow(a, b, res);
|
||||
#elif __SIZEOF_LONG_LONG__ == 8
|
||||
return __builtin_uaddll_overflow(a, b, res);
|
||||
#else
|
||||
#error "sizeof(long long) != 8"
|
||||
#endif
|
||||
#endif
|
||||
*res = a + b;
|
||||
return ULLONG_MAX - a < b;
|
||||
}
|
||||
|
@ -206,5 +206,24 @@ DEFINE_TEST(test_write_str_safe,
|
||||
},
|
||||
});
|
||||
|
||||
static int test_addu64_overflow(const struct test *t)
|
||||
{
|
||||
uint64_t res;
|
||||
bool overflow;
|
||||
|
||||
overflow = addu64_overflow(UINT64_MAX - 1, 1, &res);
|
||||
assert_return(!overflow, EXIT_FAILURE);
|
||||
assert_return(res == UINT64_MAX, EXIT_FAILURE);
|
||||
|
||||
overflow = addu64_overflow(UINT64_MAX, 1, &res);
|
||||
assert_return(overflow, EXIT_FAILURE);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
DEFINE_TEST(test_addu64_overflow,
|
||||
.description = "check implementation of addu4_overflow()",
|
||||
.need_spawn = false,
|
||||
);
|
||||
|
||||
|
||||
TESTSUITE_MAIN();
|
||||
|
Loading…
Reference in New Issue
Block a user