diff --git a/include/ssp/ssp.h b/include/ssp/ssp.h index 622e9e901ba6..de109da4959e 100644 --- a/include/ssp/ssp.h +++ b/include/ssp/ssp.h @@ -83,12 +83,19 @@ __ssp_inline rtype fun args { \ #define __ssp_redirect0(rtype, fun, args, call) \ __ssp_redirect_raw(rtype, fun, fun, args, call, 1, __ssp_bos0) -/* - * Take caution when using __ssp_overlap! Don't use it in contexts where we - * can end up with double-evaluation of a statement with some side-effects. - */ -#define __ssp_overlap(a, b, l) \ - (((a) <= (b) && (b) < (a) + (l)) || ((b) <= (a) && (a) < (b) + (l))) +#include + +static inline int +__ssp_overlap(const void *leftp, const void *rightp, __size_t sz) +{ + __uintptr_t left = (__uintptr_t)leftp; + __uintptr_t right = (__uintptr_t)rightp; + + if (left <= right) + return (SIZE_MAX - sz < left || right < left + sz); + + return (SIZE_MAX - sz < right || left < right + sz); +} __BEGIN_DECLS void __stack_chk_fail(void) __dead2; diff --git a/lib/libc/secure/memcpy_chk.c b/lib/libc/secure/memcpy_chk.c index 2a269cb475ab..ac995d00ee8c 100644 --- a/lib/libc/secure/memcpy_chk.c +++ b/lib/libc/secure/memcpy_chk.c @@ -44,7 +44,7 @@ __memcpy_chk(void * __restrict dst, const void * __restrict src, size_t len, if (len > slen) __chk_fail(); - if (__ssp_overlap((const char *)src, (const char *)dst, len)) + if (__ssp_overlap(src, dst, len)) __chk_fail(); return (memcpy(dst, src, len));