Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull locking fixes from Ingo Molnar:
"The main change is the uninlining of large refcount_t APIs, plus a
header dependency fix.

Note that the uninlining allowed us to enable the underflow/overflow
warnings unconditionally and remove the debug Kconfig switch: this
might trigger new warnings in buggy code and turn
crashes/use-after-free bugs into less harmful memory leaks"

* 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
locking/refcounts: Add missing kernel.h header to have UINT_MAX defined
locking/refcounts: Out-of-line everything

+281 -279
+13 -265
include/linux/refcount.h
··· 1 1 #ifndef _LINUX_REFCOUNT_H 2 2 #define _LINUX_REFCOUNT_H 3 3 4 - /* 5 - * Variant of atomic_t specialized for reference counts. 6 - * 7 - * The interface matches the atomic_t interface (to aid in porting) but only 8 - * provides the few functions one should use for reference counting. 9 - * 10 - * It differs in that the counter saturates at UINT_MAX and will not move once 11 - * there. This avoids wrapping the counter and causing 'spurious' 12 - * use-after-free issues. 13 - * 14 - * Memory ordering rules are slightly relaxed wrt regular atomic_t functions 15 - * and provide only what is strictly required for refcounts. 16 - * 17 - * The increments are fully relaxed; these will not provide ordering. The 18 - * rationale is that whatever is used to obtain the object we're increasing the 19 - * reference count on will provide the ordering. For locked data structures, 20 - * its the lock acquire, for RCU/lockless data structures its the dependent 21 - * load. 22 - * 23 - * Do note that inc_not_zero() provides a control dependency which will order 24 - * future stores against the inc, this ensures we'll never modify the object 25 - * if we did not in fact acquire a reference. 26 - * 27 - * The decrements will provide release order, such that all the prior loads and 28 - * stores will be issued before, it also provides a control dependency, which 29 - * will order us against the subsequent free(). 30 - * 31 - * The control dependency is against the load of the cmpxchg (ll/sc) that 32 - * succeeded. This means the stores aren't fully ordered, but this is fine 33 - * because the 1->0 transition indicates no concurrency. 34 - * 35 - * Note that the allocator is responsible for ordering things between free() 36 - * and alloc(). 37 - * 38 - */ 39 - 40 4 #include <linux/atomic.h> 41 - #include <linux/bug.h> 42 5 #include <linux/mutex.h> 43 6 #include <linux/spinlock.h> 44 - 45 - #ifdef CONFIG_DEBUG_REFCOUNT 46 - #define REFCOUNT_WARN(cond, str) WARN_ON(cond) 47 - #define __refcount_check __must_check 48 - #else 49 - #define REFCOUNT_WARN(cond, str) (void)(cond) 50 - #define __refcount_check 51 - #endif 7 + #include <linux/kernel.h> 52 8 53 9 typedef struct refcount_struct { 54 10 atomic_t refs; ··· 22 66 return atomic_read(&r->refs); 23 67 } 24 68 25 - static inline __refcount_check 26 - bool refcount_add_not_zero(unsigned int i, refcount_t *r) 27 - { 28 - unsigned int old, new, val = atomic_read(&r->refs); 69 + extern __must_check bool refcount_add_not_zero(unsigned int i, refcount_t *r); 70 + extern void refcount_add(unsigned int i, refcount_t *r); 29 71 30 - for (;;) { 31 - if (!val) 32 - return false; 72 + extern __must_check bool refcount_inc_not_zero(refcount_t *r); 73 + extern void refcount_inc(refcount_t *r); 33 74 34 - if (unlikely(val == UINT_MAX)) 35 - return true; 75 + extern __must_check bool refcount_sub_and_test(unsigned int i, refcount_t *r); 76 + extern void refcount_sub(unsigned int i, refcount_t *r); 36 77 37 - new = val + i; 38 - if (new < val) 39 - new = UINT_MAX; 40 - old = atomic_cmpxchg_relaxed(&r->refs, val, new); 41 - if (old == val) 42 - break; 78 + extern __must_check bool refcount_dec_and_test(refcount_t *r); 79 + extern void refcount_dec(refcount_t *r); 43 80 44 - val = old; 45 - } 46 - 47 - REFCOUNT_WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); 48 - 49 - return true; 50 - } 51 - 52 - static inline void refcount_add(unsigned int i, refcount_t *r) 53 - { 54 - REFCOUNT_WARN(!refcount_add_not_zero(i, r), "refcount_t: addition on 0; use-after-free.\n"); 55 - } 56 - 57 - /* 58 - * Similar to atomic_inc_not_zero(), will saturate at UINT_MAX and WARN. 59 - * 60 - * Provides no memory ordering, it is assumed the caller has guaranteed the 61 - * object memory to be stable (RCU, etc.). It does provide a control dependency 62 - * and thereby orders future stores. See the comment on top. 63 - */ 64 - static inline __refcount_check 65 - bool refcount_inc_not_zero(refcount_t *r) 66 - { 67 - unsigned int old, new, val = atomic_read(&r->refs); 68 - 69 - for (;;) { 70 - new = val + 1; 71 - 72 - if (!val) 73 - return false; 74 - 75 - if (unlikely(!new)) 76 - return true; 77 - 78 - old = atomic_cmpxchg_relaxed(&r->refs, val, new); 79 - if (old == val) 80 - break; 81 - 82 - val = old; 83 - } 84 - 85 - REFCOUNT_WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); 86 - 87 - return true; 88 - } 89 - 90 - /* 91 - * Similar to atomic_inc(), will saturate at UINT_MAX and WARN. 92 - * 93 - * Provides no memory ordering, it is assumed the caller already has a 94 - * reference on the object, will WARN when this is not so. 95 - */ 96 - static inline void refcount_inc(refcount_t *r) 97 - { 98 - REFCOUNT_WARN(!refcount_inc_not_zero(r), "refcount_t: increment on 0; use-after-free.\n"); 99 - } 100 - 101 - /* 102 - * Similar to atomic_dec_and_test(), it will WARN on underflow and fail to 103 - * decrement when saturated at UINT_MAX. 104 - * 105 - * Provides release memory ordering, such that prior loads and stores are done 106 - * before, and provides a control dependency such that free() must come after. 107 - * See the comment on top. 108 - */ 109 - static inline __refcount_check 110 - bool refcount_sub_and_test(unsigned int i, refcount_t *r) 111 - { 112 - unsigned int old, new, val = atomic_read(&r->refs); 113 - 114 - for (;;) { 115 - if (unlikely(val == UINT_MAX)) 116 - return false; 117 - 118 - new = val - i; 119 - if (new > val) { 120 - REFCOUNT_WARN(new > val, "refcount_t: underflow; use-after-free.\n"); 121 - return false; 122 - } 123 - 124 - old = atomic_cmpxchg_release(&r->refs, val, new); 125 - if (old == val) 126 - break; 127 - 128 - val = old; 129 - } 130 - 131 - return !new; 132 - } 133 - 134 - static inline __refcount_check 135 - bool refcount_dec_and_test(refcount_t *r) 136 - { 137 - return refcount_sub_and_test(1, r); 138 - } 139 - 140 - /* 141 - * Similar to atomic_dec(), it will WARN on underflow and fail to decrement 142 - * when saturated at UINT_MAX. 143 - * 144 - * Provides release memory ordering, such that prior loads and stores are done 145 - * before. 146 - */ 147 - static inline 148 - void refcount_dec(refcount_t *r) 149 - { 150 - REFCOUNT_WARN(refcount_dec_and_test(r), "refcount_t: decrement hit 0; leaking memory.\n"); 151 - } 152 - 153 - /* 154 - * No atomic_t counterpart, it attempts a 1 -> 0 transition and returns the 155 - * success thereof. 156 - * 157 - * Like all decrement operations, it provides release memory order and provides 158 - * a control dependency. 159 - * 160 - * It can be used like a try-delete operator; this explicit case is provided 161 - * and not cmpxchg in generic, because that would allow implementing unsafe 162 - * operations. 163 - */ 164 - static inline __refcount_check 165 - bool refcount_dec_if_one(refcount_t *r) 166 - { 167 - return atomic_cmpxchg_release(&r->refs, 1, 0) == 1; 168 - } 169 - 170 - /* 171 - * No atomic_t counterpart, it decrements unless the value is 1, in which case 172 - * it will return false. 173 - * 174 - * Was often done like: atomic_add_unless(&var, -1, 1) 175 - */ 176 - static inline __refcount_check 177 - bool refcount_dec_not_one(refcount_t *r) 178 - { 179 - unsigned int old, new, val = atomic_read(&r->refs); 180 - 181 - for (;;) { 182 - if (unlikely(val == UINT_MAX)) 183 - return true; 184 - 185 - if (val == 1) 186 - return false; 187 - 188 - new = val - 1; 189 - if (new > val) { 190 - REFCOUNT_WARN(new > val, "refcount_t: underflow; use-after-free.\n"); 191 - return true; 192 - } 193 - 194 - old = atomic_cmpxchg_release(&r->refs, val, new); 195 - if (old == val) 196 - break; 197 - 198 - val = old; 199 - } 200 - 201 - return true; 202 - } 203 - 204 - /* 205 - * Similar to atomic_dec_and_mutex_lock(), it will WARN on underflow and fail 206 - * to decrement when saturated at UINT_MAX. 207 - * 208 - * Provides release memory ordering, such that prior loads and stores are done 209 - * before, and provides a control dependency such that free() must come after. 210 - * See the comment on top. 211 - */ 212 - static inline __refcount_check 213 - bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock) 214 - { 215 - if (refcount_dec_not_one(r)) 216 - return false; 217 - 218 - mutex_lock(lock); 219 - if (!refcount_dec_and_test(r)) { 220 - mutex_unlock(lock); 221 - return false; 222 - } 223 - 224 - return true; 225 - } 226 - 227 - /* 228 - * Similar to atomic_dec_and_lock(), it will WARN on underflow and fail to 229 - * decrement when saturated at UINT_MAX. 230 - * 231 - * Provides release memory ordering, such that prior loads and stores are done 232 - * before, and provides a control dependency such that free() must come after. 233 - * See the comment on top. 234 - */ 235 - static inline __refcount_check 236 - bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock) 237 - { 238 - if (refcount_dec_not_one(r)) 239 - return false; 240 - 241 - spin_lock(lock); 242 - if (!refcount_dec_and_test(r)) { 243 - spin_unlock(lock); 244 - return false; 245 - } 246 - 247 - return true; 248 - } 81 + extern __must_check bool refcount_dec_if_one(refcount_t *r); 82 + extern __must_check bool refcount_dec_not_one(refcount_t *r); 83 + extern __must_check bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock); 84 + extern __must_check bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock); 249 85 250 86 #endif /* _LINUX_REFCOUNT_H */
-13
lib/Kconfig.debug
··· 729 729 730 730 source "lib/Kconfig.kasan" 731 731 732 - config DEBUG_REFCOUNT 733 - bool "Verbose refcount checks" 734 - help 735 - Say Y here if you want reference counters (refcount_t and kref) to 736 - generate WARNs on dubious usage. Without this refcount_t will still 737 - be a saturating counter and avoid Use-After-Free by turning it into 738 - a resource leak Denial-Of-Service. 739 - 740 - Use of this option will increase kernel text size but will alert the 741 - admin of potential abuse. 742 - 743 - If in doubt, say "N". 744 - 745 732 endmenu # "Memory Debugging" 746 733 747 734 config ARCH_HAS_KCOV
+1 -1
lib/Makefile
··· 38 38 gcd.o lcm.o list_sort.o uuid.o flex_array.o iov_iter.o clz_ctz.o \ 39 39 bsearch.o find_bit.o llist.o memweight.o kfifo.o \ 40 40 percpu-refcount.o percpu_ida.o rhashtable.o reciprocal_div.o \ 41 - once.o 41 + once.o refcount.o 42 42 obj-y += string_helpers.o 43 43 obj-$(CONFIG_TEST_STRING_HELPERS) += test-string_helpers.o 44 44 obj-y += hexdump.o
+267
lib/refcount.c
··· 1 + /* 2 + * Variant of atomic_t specialized for reference counts. 3 + * 4 + * The interface matches the atomic_t interface (to aid in porting) but only 5 + * provides the few functions one should use for reference counting. 6 + * 7 + * It differs in that the counter saturates at UINT_MAX and will not move once 8 + * there. This avoids wrapping the counter and causing 'spurious' 9 + * use-after-free issues. 10 + * 11 + * Memory ordering rules are slightly relaxed wrt regular atomic_t functions 12 + * and provide only what is strictly required for refcounts. 13 + * 14 + * The increments are fully relaxed; these will not provide ordering. The 15 + * rationale is that whatever is used to obtain the object we're increasing the 16 + * reference count on will provide the ordering. For locked data structures, 17 + * its the lock acquire, for RCU/lockless data structures its the dependent 18 + * load. 19 + * 20 + * Do note that inc_not_zero() provides a control dependency which will order 21 + * future stores against the inc, this ensures we'll never modify the object 22 + * if we did not in fact acquire a reference. 23 + * 24 + * The decrements will provide release order, such that all the prior loads and 25 + * stores will be issued before, it also provides a control dependency, which 26 + * will order us against the subsequent free(). 27 + * 28 + * The control dependency is against the load of the cmpxchg (ll/sc) that 29 + * succeeded. This means the stores aren't fully ordered, but this is fine 30 + * because the 1->0 transition indicates no concurrency. 31 + * 32 + * Note that the allocator is responsible for ordering things between free() 33 + * and alloc(). 34 + * 35 + */ 36 + 37 + #include <linux/refcount.h> 38 + #include <linux/bug.h> 39 + 40 + bool refcount_add_not_zero(unsigned int i, refcount_t *r) 41 + { 42 + unsigned int old, new, val = atomic_read(&r->refs); 43 + 44 + for (;;) { 45 + if (!val) 46 + return false; 47 + 48 + if (unlikely(val == UINT_MAX)) 49 + return true; 50 + 51 + new = val + i; 52 + if (new < val) 53 + new = UINT_MAX; 54 + old = atomic_cmpxchg_relaxed(&r->refs, val, new); 55 + if (old == val) 56 + break; 57 + 58 + val = old; 59 + } 60 + 61 + WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); 62 + 63 + return true; 64 + } 65 + EXPORT_SYMBOL_GPL(refcount_add_not_zero); 66 + 67 + void refcount_add(unsigned int i, refcount_t *r) 68 + { 69 + WARN(!refcount_add_not_zero(i, r), "refcount_t: addition on 0; use-after-free.\n"); 70 + } 71 + EXPORT_SYMBOL_GPL(refcount_add); 72 + 73 + /* 74 + * Similar to atomic_inc_not_zero(), will saturate at UINT_MAX and WARN. 75 + * 76 + * Provides no memory ordering, it is assumed the caller has guaranteed the 77 + * object memory to be stable (RCU, etc.). It does provide a control dependency 78 + * and thereby orders future stores. See the comment on top. 79 + */ 80 + bool refcount_inc_not_zero(refcount_t *r) 81 + { 82 + unsigned int old, new, val = atomic_read(&r->refs); 83 + 84 + for (;;) { 85 + new = val + 1; 86 + 87 + if (!val) 88 + return false; 89 + 90 + if (unlikely(!new)) 91 + return true; 92 + 93 + old = atomic_cmpxchg_relaxed(&r->refs, val, new); 94 + if (old == val) 95 + break; 96 + 97 + val = old; 98 + } 99 + 100 + WARN(new == UINT_MAX, "refcount_t: saturated; leaking memory.\n"); 101 + 102 + return true; 103 + } 104 + EXPORT_SYMBOL_GPL(refcount_inc_not_zero); 105 + 106 + /* 107 + * Similar to atomic_inc(), will saturate at UINT_MAX and WARN. 108 + * 109 + * Provides no memory ordering, it is assumed the caller already has a 110 + * reference on the object, will WARN when this is not so. 111 + */ 112 + void refcount_inc(refcount_t *r) 113 + { 114 + WARN(!refcount_inc_not_zero(r), "refcount_t: increment on 0; use-after-free.\n"); 115 + } 116 + EXPORT_SYMBOL_GPL(refcount_inc); 117 + 118 + bool refcount_sub_and_test(unsigned int i, refcount_t *r) 119 + { 120 + unsigned int old, new, val = atomic_read(&r->refs); 121 + 122 + for (;;) { 123 + if (unlikely(val == UINT_MAX)) 124 + return false; 125 + 126 + new = val - i; 127 + if (new > val) { 128 + WARN(new > val, "refcount_t: underflow; use-after-free.\n"); 129 + return false; 130 + } 131 + 132 + old = atomic_cmpxchg_release(&r->refs, val, new); 133 + if (old == val) 134 + break; 135 + 136 + val = old; 137 + } 138 + 139 + return !new; 140 + } 141 + EXPORT_SYMBOL_GPL(refcount_sub_and_test); 142 + 143 + /* 144 + * Similar to atomic_dec_and_test(), it will WARN on underflow and fail to 145 + * decrement when saturated at UINT_MAX. 146 + * 147 + * Provides release memory ordering, such that prior loads and stores are done 148 + * before, and provides a control dependency such that free() must come after. 149 + * See the comment on top. 150 + */ 151 + bool refcount_dec_and_test(refcount_t *r) 152 + { 153 + return refcount_sub_and_test(1, r); 154 + } 155 + EXPORT_SYMBOL_GPL(refcount_dec_and_test); 156 + 157 + /* 158 + * Similar to atomic_dec(), it will WARN on underflow and fail to decrement 159 + * when saturated at UINT_MAX. 160 + * 161 + * Provides release memory ordering, such that prior loads and stores are done 162 + * before. 163 + */ 164 + 165 + void refcount_dec(refcount_t *r) 166 + { 167 + WARN(refcount_dec_and_test(r), "refcount_t: decrement hit 0; leaking memory.\n"); 168 + } 169 + EXPORT_SYMBOL_GPL(refcount_dec); 170 + 171 + /* 172 + * No atomic_t counterpart, it attempts a 1 -> 0 transition and returns the 173 + * success thereof. 174 + * 175 + * Like all decrement operations, it provides release memory order and provides 176 + * a control dependency. 177 + * 178 + * It can be used like a try-delete operator; this explicit case is provided 179 + * and not cmpxchg in generic, because that would allow implementing unsafe 180 + * operations. 181 + */ 182 + bool refcount_dec_if_one(refcount_t *r) 183 + { 184 + return atomic_cmpxchg_release(&r->refs, 1, 0) == 1; 185 + } 186 + EXPORT_SYMBOL_GPL(refcount_dec_if_one); 187 + 188 + /* 189 + * No atomic_t counterpart, it decrements unless the value is 1, in which case 190 + * it will return false. 191 + * 192 + * Was often done like: atomic_add_unless(&var, -1, 1) 193 + */ 194 + bool refcount_dec_not_one(refcount_t *r) 195 + { 196 + unsigned int old, new, val = atomic_read(&r->refs); 197 + 198 + for (;;) { 199 + if (unlikely(val == UINT_MAX)) 200 + return true; 201 + 202 + if (val == 1) 203 + return false; 204 + 205 + new = val - 1; 206 + if (new > val) { 207 + WARN(new > val, "refcount_t: underflow; use-after-free.\n"); 208 + return true; 209 + } 210 + 211 + old = atomic_cmpxchg_release(&r->refs, val, new); 212 + if (old == val) 213 + break; 214 + 215 + val = old; 216 + } 217 + 218 + return true; 219 + } 220 + EXPORT_SYMBOL_GPL(refcount_dec_not_one); 221 + 222 + /* 223 + * Similar to atomic_dec_and_mutex_lock(), it will WARN on underflow and fail 224 + * to decrement when saturated at UINT_MAX. 225 + * 226 + * Provides release memory ordering, such that prior loads and stores are done 227 + * before, and provides a control dependency such that free() must come after. 228 + * See the comment on top. 229 + */ 230 + bool refcount_dec_and_mutex_lock(refcount_t *r, struct mutex *lock) 231 + { 232 + if (refcount_dec_not_one(r)) 233 + return false; 234 + 235 + mutex_lock(lock); 236 + if (!refcount_dec_and_test(r)) { 237 + mutex_unlock(lock); 238 + return false; 239 + } 240 + 241 + return true; 242 + } 243 + EXPORT_SYMBOL_GPL(refcount_dec_and_mutex_lock); 244 + 245 + /* 246 + * Similar to atomic_dec_and_lock(), it will WARN on underflow and fail to 247 + * decrement when saturated at UINT_MAX. 248 + * 249 + * Provides release memory ordering, such that prior loads and stores are done 250 + * before, and provides a control dependency such that free() must come after. 251 + * See the comment on top. 252 + */ 253 + bool refcount_dec_and_lock(refcount_t *r, spinlock_t *lock) 254 + { 255 + if (refcount_dec_not_one(r)) 256 + return false; 257 + 258 + spin_lock(lock); 259 + if (!refcount_dec_and_test(r)) { 260 + spin_unlock(lock); 261 + return false; 262 + } 263 + 264 + return true; 265 + } 266 + EXPORT_SYMBOL_GPL(refcount_dec_and_lock); 267 +