Skip to content

Commit 97a1420

Browse files
willdeaconIngo Molnar
authored andcommitted
locking/refcount: Ensure integer operands are treated as signed
In preparation for changing the saturation point of REFCOUNT_FULL to INT_MIN/2, change the type of integer operands passed into the API from 'unsigned int' to 'int' so that we can avoid casting during comparisons when we don't want to fall foul of C integral conversion rules for signed and unsigned types. Since the kernel is compiled with '-fno-strict-overflow', we don't need to worry about the UB introduced by signed overflow here. Furthermore, we're already making heavy use of the atomic_t API, which operates exclusively on signed types. Signed-off-by: Will Deacon <[email protected]> Reviewed-by: Ard Biesheuvel <[email protected]> Reviewed-by: Kees Cook <[email protected]> Tested-by: Hanjun Guo <[email protected]> Cc: Ard Biesheuvel <[email protected]> Cc: Elena Reshetova <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent 23e6b16 commit 97a1420

File tree

2 files changed

+10
-10
lines changed

2 files changed

+10
-10
lines changed

include/linux/refcount.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ typedef struct refcount_struct {
2828
* @r: the refcount
2929
* @n: value to which the refcount will be set
3030
*/
31-
static inline void refcount_set(refcount_t *r, unsigned int n)
31+
static inline void refcount_set(refcount_t *r, int n)
3232
{
3333
atomic_set(&r->refs, n);
3434
}
@@ -44,13 +44,13 @@ static inline unsigned int refcount_read(const refcount_t *r)
4444
return atomic_read(&r->refs);
4545
}
4646

47-
extern __must_check bool refcount_add_not_zero_checked(unsigned int i, refcount_t *r);
48-
extern void refcount_add_checked(unsigned int i, refcount_t *r);
47+
extern __must_check bool refcount_add_not_zero_checked(int i, refcount_t *r);
48+
extern void refcount_add_checked(int i, refcount_t *r);
4949

5050
extern __must_check bool refcount_inc_not_zero_checked(refcount_t *r);
5151
extern void refcount_inc_checked(refcount_t *r);
5252

53-
extern __must_check bool refcount_sub_and_test_checked(unsigned int i, refcount_t *r);
53+
extern __must_check bool refcount_sub_and_test_checked(int i, refcount_t *r);
5454

5555
extern __must_check bool refcount_dec_and_test_checked(refcount_t *r);
5656
extern void refcount_dec_checked(refcount_t *r);
@@ -79,12 +79,12 @@ extern void refcount_dec_checked(refcount_t *r);
7979
# ifdef CONFIG_ARCH_HAS_REFCOUNT
8080
# include <asm/refcount.h>
8181
# else
82-
static inline __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r)
82+
static inline __must_check bool refcount_add_not_zero(int i, refcount_t *r)
8383
{
8484
return atomic_add_unless(&r->refs, i, 0);
8585
}
8686

87-
static inline void refcount_add(unsigned int i, refcount_t *r)
87+
static inline void refcount_add(int i, refcount_t *r)
8888
{
8989
atomic_add(i, &r->refs);
9090
}
@@ -99,7 +99,7 @@ static inline void refcount_inc(refcount_t *r)
9999
atomic_inc(&r->refs);
100100
}
101101

102-
static inline __must_check bool refcount_sub_and_test(unsigned int i, refcount_t *r)
102+
static inline __must_check bool refcount_sub_and_test(int i, refcount_t *r)
103103
{
104104
return atomic_sub_and_test(i, &r->refs);
105105
}

lib/refcount.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
*
6262
* Return: false if the passed refcount is 0, true otherwise
6363
*/
64-
bool refcount_add_not_zero_checked(unsigned int i, refcount_t *r)
64+
bool refcount_add_not_zero_checked(int i, refcount_t *r)
6565
{
6666
unsigned int new, val = atomic_read(&r->refs);
6767

@@ -101,7 +101,7 @@ EXPORT_SYMBOL(refcount_add_not_zero_checked);
101101
* cases, refcount_inc(), or one of its variants, should instead be used to
102102
* increment a reference count.
103103
*/
104-
void refcount_add_checked(unsigned int i, refcount_t *r)
104+
void refcount_add_checked(int i, refcount_t *r)
105105
{
106106
WARN_ONCE(!refcount_add_not_zero_checked(i, r), "refcount_t: addition on 0; use-after-free.\n");
107107
}
@@ -180,7 +180,7 @@ EXPORT_SYMBOL(refcount_inc_checked);
180180
*
181181
* Return: true if the resulting refcount is 0, false otherwise
182182
*/
183-
bool refcount_sub_and_test_checked(unsigned int i, refcount_t *r)
183+
bool refcount_sub_and_test_checked(int i, refcount_t *r)
184184
{
185185
unsigned int new, val = atomic_read(&r->refs);
186186

0 commit comments

Comments
 (0)