diff options
author | Kees Cook <keescook@chromium.org> | 2024-02-20 21:16:38 -0800 |
---|---|---|
committer | Kees Cook <keescook@chromium.org> | 2024-02-29 13:38:02 -0800 |
commit | 99db710f768e988e70f1164537bf533a017be24d (patch) | |
tree | 385cf2015d588e9cde29d887463f989c553cf2bb | |
parent | e7549481255167dcdab355c539562c7ace17e111 (diff) |
refcount: Annotated intentional signed integer wrap-around
Mark the various refcount_t functions with __signed_wrap, as we depend
on the wrapping behavior to detect the overflow and perform saturation.
Silences warnings seen with the LKDTM REFCOUNT_* tests:
UBSAN: signed-integer-overflow in ../include/linux/refcount.h:189:11
2147483647 + 1 cannot be represented in type 'int'
Reviewed-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/r/20240221051634.work.287-kees@kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
-rw-r--r-- | include/linux/refcount.h | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/include/linux/refcount.h b/include/linux/refcount.h index 85c6df0d1bef..59b3b752394d 100644 --- a/include/linux/refcount.h +++ b/include/linux/refcount.h @@ -136,7 +136,8 @@ static inline unsigned int refcount_read(const refcount_t *r) return atomic_read(&r->refs); } -static inline __must_check bool __refcount_add_not_zero(int i, refcount_t *r, int *oldp) +static inline __must_check __signed_wrap +bool __refcount_add_not_zero(int i, refcount_t *r, int *oldp) { int old = refcount_read(r); @@ -177,7 +178,8 @@ static inline __must_check bool refcount_add_not_zero(int i, refcount_t *r) return __refcount_add_not_zero(i, r, NULL); } -static inline void __refcount_add(int i, refcount_t *r, int *oldp) +static inline __signed_wrap +void __refcount_add(int i, refcount_t *r, int *oldp) { int old = atomic_fetch_add_relaxed(i, &r->refs); @@ -256,7 +258,8 @@ static inline void refcount_inc(refcount_t *r) __refcount_inc(r, NULL); } -static inline __must_check bool __refcount_sub_and_test(int i, refcount_t *r, int *oldp) +static inline __must_check __signed_wrap +bool __refcount_sub_and_test(int i, refcount_t *r, int *oldp) { int old = atomic_fetch_sub_release(i, &r->refs); |