This allows replacements of the idioms "var += offset" and "var -= offset" with the inc_wrap() and dec_wrap() helpers respectively. They will avoid wrap-around sanitizer instrumentation.
Cc: Rasmus Villemoes <[email protected]> Cc: Mark Rutland <[email protected]> Cc: "Gustavo A. R. Silva" <[email protected]> Cc: [email protected] Signed-off-by: Kees Cook <[email protected]> --- include/linux/overflow.h | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/include/linux/overflow.h b/include/linux/overflow.h index 4f945e9e7881..080b18b84498 100644 --- a/include/linux/overflow.h +++ b/include/linux/overflow.h @@ -138,6 +138,22 @@ static inline bool __must_check __must_check_overflow(bool overflow) __sum; \ }) +/** + * add_wrap() - Intentionally perform a wrapping increment + * @a: variable to be incremented + * @b: amount to add + * + * Increments @a by @b with wrap-around. Returns the resulting + * value of @a. Will not trip any wrap-around sanitizers. + */ +#define inc_wrap(var, offset) \ + ({ \ + if (check_add_overflow(var, offset, &var)) { \ + /* do nothing */ \ + } \ + var; \ + }) + /** * check_sub_overflow() - Calculate subtraction with overflow checking * @a: minuend; value to subtract from @@ -169,6 +185,22 @@ static inline bool __must_check __must_check_overflow(bool overflow) __val; \ }) +/** + * dec_wrap() - Intentionally perform a wrapping decrement + * @a: variable to be decremented + * @b: amount to subtract + * + * Decrements @a by @b with wrap-around. Returns the resulting + * value of @a. Will not trip any wrap-around sanitizers. + */ +#define dec_wrap(var, offset) \ + ({ \ + if (check_sub_overflow(var, offset, &var)) { \ + /* do nothing */ \ + } \ + var; \ + }) + /** * check_mul_overflow() - Calculate multiplication with overflow checking * @a: first factor -- 2.34.1
