]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
unshare: fix nsproxy leak in ksys_unshare() on set_cred_ucounts() failure
authorMichal Grzedzicki <mge@meta.com>
Fri, 13 Feb 2026 19:39:59 +0000 (11:39 -0800)
committerAndrew Morton <akpm@linux-foundation.org>
Sat, 28 Mar 2026 04:19:32 +0000 (21:19 -0700)
When set_cred_ucounts() fails in ksys_unshare() new_nsproxy is leaked.

Let's call put_nsproxy() if that happens.

Link: https://lkml.kernel.org/r/20260213193959.2556730-1-mge@meta.com
Fixes: 905ae01c4ae2 ("Add a reference to ucounts for each cred")
Signed-off-by: Michal Grzedzicki <mge@meta.com>
Reviewed-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Alexey Gladkov (Intel) <legion@kernel.org>
Cc: Ben Segall <bsegall@google.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Kees Cook <kees@kernel.org>
Cc: "Liam R. Howlett" <Liam.Howlett@oracle.com>
Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Valentin Schneider <vschneid@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
kernel/fork.c

index bc2bf58b93b6524ca8510474634c7e921ac25f9a..1ec0caea6a7e712d02ebbc9c56d8a91d7c63c3ad 100644 (file)
@@ -3174,11 +3174,10 @@ int ksys_unshare(unsigned long unshare_flags)
                                         new_cred, new_fs);
        if (err)
                goto bad_unshare_cleanup_cred;
-
        if (new_cred) {
                err = set_cred_ucounts(new_cred);
                if (err)
-                       goto bad_unshare_cleanup_cred;
+                       goto bad_unshare_cleanup_nsproxy;
        }
 
        if (new_fs || new_fd || do_sysvsem || new_cred || new_nsproxy) {
@@ -3194,8 +3193,10 @@ int ksys_unshare(unsigned long unshare_flags)
                        shm_init_task(current);
                }
 
-               if (new_nsproxy)
+               if (new_nsproxy) {
                        switch_task_namespaces(current, new_nsproxy);
+                       new_nsproxy = NULL;
+               }
 
                task_lock(current);
 
@@ -3224,13 +3225,15 @@ int ksys_unshare(unsigned long unshare_flags)
 
        perf_event_namespaces(current);
 
+bad_unshare_cleanup_nsproxy:
+       if (new_nsproxy)
+               put_nsproxy(new_nsproxy);
 bad_unshare_cleanup_cred:
        if (new_cred)
                put_cred(new_cred);
 bad_unshare_cleanup_fd:
        if (new_fd)
                put_files_struct(new_fd);
-
 bad_unshare_cleanup_fs:
        if (new_fs)
                free_fs_struct(new_fs);