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

ns: add asserts for active refcount underflow

Add a few more assert to detect active reference count underflows.

Link: https://patch.msgid.link/20251109-namespace-6-19-fixes-v1-6-ae8a4ad5a3b3@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>

+14 -5
-1
include/linux/ns_common.h
··· 294 294 295 295 static __always_inline struct ns_common *__must_check ns_get_unless_inactive(struct ns_common *ns) 296 296 { 297 - VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) && !__ns_ref_read(ns)); 298 297 if (!__ns_ref_active_read(ns)) { 299 298 VFS_WARN_ON_ONCE(is_ns_init_id(ns)); 300 299 return NULL;
+14 -4
kernel/nscommon.c
··· 170 170 if (is_ns_init_id(ns)) 171 171 return; 172 172 173 - if (!atomic_dec_and_test(&ns->__ns_ref_active)) 173 + if (!atomic_dec_and_test(&ns->__ns_ref_active)) { 174 + VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) < 0); 174 175 return; 176 + } 175 177 176 178 VFS_WARN_ON_ONCE(is_ns_init_id(ns)); 177 179 VFS_WARN_ON_ONCE(!__ns_ref_read(ns)); ··· 183 181 if (!ns) 184 182 return; 185 183 VFS_WARN_ON_ONCE(is_ns_init_id(ns)); 186 - if (!atomic_dec_and_test(&ns->__ns_ref_active)) 184 + if (!atomic_dec_and_test(&ns->__ns_ref_active)) { 185 + VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) < 0); 187 186 return; 187 + } 188 188 } 189 189 } 190 190 ··· 284 280 */ 285 281 void __ns_ref_active_get(struct ns_common *ns) 286 282 { 283 + int prev; 284 + 287 285 /* Initial namespaces are always active. */ 288 286 if (is_ns_init_id(ns)) 289 287 return; 290 288 291 289 /* If we didn't resurrect the namespace we're done. */ 292 - if (atomic_fetch_add(1, &ns->__ns_ref_active)) 290 + prev = atomic_fetch_add(1, &ns->__ns_ref_active); 291 + VFS_WARN_ON_ONCE(prev < 0); 292 + if (likely(prev)) 293 293 return; 294 294 295 295 /* ··· 306 298 return; 307 299 308 300 VFS_WARN_ON_ONCE(is_ns_init_id(ns)); 309 - if (atomic_fetch_add(1, &ns->__ns_ref_active)) 301 + prev = atomic_fetch_add(1, &ns->__ns_ref_active); 302 + VFS_WARN_ON_ONCE(prev < 0); 303 + if (likely(prev)) 310 304 return; 311 305 } 312 306 }