Commit 99db710f authored by Kees Cook's avatar Kees Cook

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: default avatarMiguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/r/20240221051634.work.287-kees@kernel.orgSigned-off-by: default avatarKees Cook <keescook@chromium.org>
parent e7549481
...@@ -136,7 +136,8 @@ static inline unsigned int refcount_read(const refcount_t *r) ...@@ -136,7 +136,8 @@ static inline unsigned int refcount_read(const refcount_t *r)
return atomic_read(&r->refs); 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); int old = refcount_read(r);
...@@ -177,7 +178,8 @@ static inline __must_check bool refcount_add_not_zero(int i, refcount_t *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); 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); int old = atomic_fetch_add_relaxed(i, &r->refs);
...@@ -256,7 +258,8 @@ static inline void refcount_inc(refcount_t *r) ...@@ -256,7 +258,8 @@ static inline void refcount_inc(refcount_t *r)
__refcount_inc(r, NULL); __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); int old = atomic_fetch_sub_release(i, &r->refs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment