Commit 6160968cee8b90a5dd95318d716e31d7775c4ef3
Committed by
Linus Torvalds
1 parent
c095ba7224
Exists in
master
and in
20 other branches
userns: unshare_userns(&cred) should not populate cred on failure
unshare_userns(new_cred) does *new_cred = prepare_creds() before create_user_ns() which can fail. However, the caller expects that it doesn't need to take care of new_cred if unshare_userns() fails. We could change the single caller, sys_unshare(), but I think it would be more clean to avoid the side effects on failure, so with this patch unshare_userns() does put_cred() itself and initializes *new_cred only if create_user_ns() succeeeds. Cc: stable@vger.kernel.org Signed-off-by: Oleg Nesterov <oleg@redhat.com> Reviewed-by: Andy Lutomirski <luto@amacapital.net> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 9 additions and 4 deletions Side-by-side Diff
kernel/user_namespace.c
... | ... | @@ -105,16 +105,21 @@ |
105 | 105 | int unshare_userns(unsigned long unshare_flags, struct cred **new_cred) |
106 | 106 | { |
107 | 107 | struct cred *cred; |
108 | + int err = -ENOMEM; | |
108 | 109 | |
109 | 110 | if (!(unshare_flags & CLONE_NEWUSER)) |
110 | 111 | return 0; |
111 | 112 | |
112 | 113 | cred = prepare_creds(); |
113 | - if (!cred) | |
114 | - return -ENOMEM; | |
114 | + if (cred) { | |
115 | + err = create_user_ns(cred); | |
116 | + if (err) | |
117 | + put_cred(cred); | |
118 | + else | |
119 | + *new_cred = cred; | |
120 | + } | |
115 | 121 | |
116 | - *new_cred = cred; | |
117 | - return create_user_ns(cred); | |
122 | + return err; | |
118 | 123 | } |
119 | 124 | |
120 | 125 | void free_user_ns(struct user_namespace *ns) |