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

kmemleak: Protect the seq start/next/stop sequence by rcu_read_lock()

Objects passed to kmemleak_seq_next() have an incremented reference
count (hence not freed) but they may point via object_list.next to
other freed objects. To avoid this, the whole start/next/stop sequence
must be protected by rcu_read_lock().

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Catalin Marinas and committed by
Linus Torvalds
f5886c7f 84210aeb

+1 -3
+1 -3
mm/kmemleak.c
··· 1217 1217 } 1218 1218 object = NULL; 1219 1219 out: 1220 - rcu_read_unlock(); 1221 1220 return object; 1222 1221 } 1223 1222 ··· 1232 1233 1233 1234 ++(*pos); 1234 1235 1235 - rcu_read_lock(); 1236 1236 list_for_each_continue_rcu(n, &object_list) { 1237 1237 next_obj = list_entry(n, struct kmemleak_object, object_list); 1238 1238 if (get_object(next_obj)) 1239 1239 break; 1240 1240 } 1241 - rcu_read_unlock(); 1242 1241 1243 1242 put_object(prev_obj); 1244 1243 return next_obj; ··· 1252 1255 * kmemleak_seq_start may return ERR_PTR if the scan_mutex 1253 1256 * waiting was interrupted, so only release it if !IS_ERR. 1254 1257 */ 1258 + rcu_read_unlock(); 1255 1259 mutex_unlock(&scan_mutex); 1256 1260 if (v) 1257 1261 put_object(v);