Unverified Commit 57b39aab authored by Christian Brauner's avatar Christian Brauner
Browse files

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: default avatarChristian Brauner <brauner@kernel.org>
parent f8d5a897
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -294,7 +294,6 @@ void __ns_ref_active_put(struct ns_common *ns);

static __always_inline struct ns_common *__must_check ns_get_unless_inactive(struct ns_common *ns)
{
	VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) && !__ns_ref_read(ns));
	if (!__ns_ref_active_read(ns)) {
		VFS_WARN_ON_ONCE(is_ns_init_id(ns));
		return NULL;
+14 −4
Original line number Diff line number Diff line
@@ -170,8 +170,10 @@ void __ns_ref_active_put(struct ns_common *ns)
	if (is_ns_init_id(ns))
		return;

	if (!atomic_dec_and_test(&ns->__ns_ref_active))
	if (!atomic_dec_and_test(&ns->__ns_ref_active)) {
		VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) < 0);
		return;
	}

	VFS_WARN_ON_ONCE(is_ns_init_id(ns));
	VFS_WARN_ON_ONCE(!__ns_ref_read(ns));
@@ -181,10 +183,12 @@ void __ns_ref_active_put(struct ns_common *ns)
		if (!ns)
			return;
		VFS_WARN_ON_ONCE(is_ns_init_id(ns));
		if (!atomic_dec_and_test(&ns->__ns_ref_active))
		if (!atomic_dec_and_test(&ns->__ns_ref_active)) {
			VFS_WARN_ON_ONCE(__ns_ref_active_read(ns) < 0);
			return;
		}
	}
}

/*
 * The active reference count works by having each namespace that gets
@@ -280,12 +284,16 @@ void __ns_ref_active_put(struct ns_common *ns)
 */
void __ns_ref_active_get(struct ns_common *ns)
{
	int prev;

	/* Initial namespaces are always active. */
	if (is_ns_init_id(ns))
		return;

	/* If we didn't resurrect the namespace we're done. */
	if (atomic_fetch_add(1, &ns->__ns_ref_active))
	prev = atomic_fetch_add(1, &ns->__ns_ref_active);
	VFS_WARN_ON_ONCE(prev < 0);
	if (likely(prev))
		return;

	/*
@@ -298,7 +306,9 @@ void __ns_ref_active_get(struct ns_common *ns)
			return;

		VFS_WARN_ON_ONCE(is_ns_init_id(ns));
		if (atomic_fetch_add(1, &ns->__ns_ref_active))
		prev = atomic_fetch_add(1, &ns->__ns_ref_active);
		VFS_WARN_ON_ONCE(prev < 0);
		if (likely(prev))
			return;
	}
}