diff options
Diffstat (limited to 'kernel/cred.c')
-rw-r--r-- | kernel/cred.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/kernel/cred.c b/kernel/cred.c index 13697ca2bb38..ff7bc071991c 100644 --- a/kernel/cred.c +++ b/kernel/cred.c | |||
@@ -274,6 +274,7 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) | |||
274 | struct thread_group_cred *tgcred; | 274 | struct thread_group_cred *tgcred; |
275 | #endif | 275 | #endif |
276 | struct cred *new; | 276 | struct cred *new; |
277 | int ret; | ||
277 | 278 | ||
278 | mutex_init(&p->cred_exec_mutex); | 279 | mutex_init(&p->cred_exec_mutex); |
279 | 280 | ||
@@ -293,6 +294,12 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) | |||
293 | if (!new) | 294 | if (!new) |
294 | return -ENOMEM; | 295 | return -ENOMEM; |
295 | 296 | ||
297 | if (clone_flags & CLONE_NEWUSER) { | ||
298 | ret = create_user_ns(new); | ||
299 | if (ret < 0) | ||
300 | goto error_put; | ||
301 | } | ||
302 | |||
296 | #ifdef CONFIG_KEYS | 303 | #ifdef CONFIG_KEYS |
297 | /* new threads get their own thread keyrings if their parent already | 304 | /* new threads get their own thread keyrings if their parent already |
298 | * had one */ | 305 | * had one */ |
@@ -309,8 +316,8 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) | |||
309 | if (!(clone_flags & CLONE_THREAD)) { | 316 | if (!(clone_flags & CLONE_THREAD)) { |
310 | tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL); | 317 | tgcred = kmalloc(sizeof(*tgcred), GFP_KERNEL); |
311 | if (!tgcred) { | 318 | if (!tgcred) { |
312 | put_cred(new); | 319 | ret = -ENOMEM; |
313 | return -ENOMEM; | 320 | goto error_put; |
314 | } | 321 | } |
315 | atomic_set(&tgcred->usage, 1); | 322 | atomic_set(&tgcred->usage, 1); |
316 | spin_lock_init(&tgcred->lock); | 323 | spin_lock_init(&tgcred->lock); |
@@ -325,6 +332,10 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) | |||
325 | atomic_inc(&new->user->processes); | 332 | atomic_inc(&new->user->processes); |
326 | p->cred = p->real_cred = get_cred(new); | 333 | p->cred = p->real_cred = get_cred(new); |
327 | return 0; | 334 | return 0; |
335 | |||
336 | error_put: | ||
337 | put_cred(new); | ||
338 | return ret; | ||
328 | } | 339 | } |
329 | 340 | ||
330 | /** | 341 | /** |