aboutsummaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorChristian Brauner <brauner@kernel.org>2026-09-30 15:32:08 +0200
committerChristian Brauner <brauner@kernel.org>2026-10-01 14:20:07 +0200
commit0b6f31a3c0b16066f812e94b52a704174a6f23cd (patch)
tree519ec1d19571b3647677a8a1e6cc12fadfae2ae3 /include/linux
parent75f4197f1e11d2eb75c2d6f916a7d4764db621e5 (diff)
unshare: don't drop active namespace references that were never taken
Active references on the namespaces of an nsproxy are taken when the nsproxy is installed into a task in switch_task_namespaces() and copy_namespaces() and dropped again by put_nsproxy() through deactivate_nsproxy(). But ksys_unshare() calls put_nsproxy() on an nsproxy that was never installed when set_cred_ucounts() fails. The new namespaces of that nsproxy go from zero to minus one and the namespaces shared with the caller lose a reference that belongs to the nsproxy the caller keeps using: WARNING: kernel/nscommon.c:171 at __ns_ref_active_put+0x1cd/0x230 nsproxy_ns_active_put deactivate_nsproxy ksys_unshare Afterwards the namespaces the caller lives in aren't listed by listns() anymore. set_cred_ucounts() only fails when alloc_ucounts() can't allocate and it only allocates when the real uid of the caller differs from its effective uid. Commit cefd55bd2159 ("nsproxy: fix free_nsproxy() and simplify create_new_namespaces()") separated the two cases on purpose. nsproxy_free() frees an nsproxy that was prepared but never installed and that's what a failed setns() uses in put_nsset(). Export it and use it for a failed unshare() as well. Fixes: a98621a0f187 ("unshare: fix nsproxy leak in ksys_unshare() on set_cred_ucounts() failure") Cc: stable@vger.kernel.org # v7.1+ Link: https://patch.msgid.link/20260930-work-mount-fixes-3-v1-16-be34c83956ae@kernel.org Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/nsproxy.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/nsproxy.h b/include/linux/nsproxy.h
index 5a67648721c7..dc2447f5f092 100644
--- a/include/linux/nsproxy.h
+++ b/include/linux/nsproxy.h
@@ -100,6 +100,7 @@ void exit_cred_namespaces(struct task_struct *tsk);
void switch_task_namespaces(struct task_struct *tsk, struct nsproxy *new);
int exec_task_namespaces(void);
void deactivate_nsproxy(struct nsproxy *ns);
+void nsproxy_free(struct nsproxy *ns);
int unshare_nsproxy_namespaces(unsigned long, struct nsproxy **,
struct cred *, struct fs_struct *);
int __init nsproxy_cache_init(void);