diff options
Diffstat (limited to 'kernel/cred.c')
-rw-r--r-- | kernel/cred.c | 90 |
1 files changed, 25 insertions, 65 deletions
diff --git a/kernel/cred.c b/kernel/cred.c index 62af1816c235..60bc8b1e32e6 100644 --- a/kernel/cred.c +++ b/kernel/cred.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/init_task.h> | 17 | #include <linux/init_task.h> |
18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
19 | #include <linux/cn_proc.h> | 19 | #include <linux/cn_proc.h> |
20 | #include "cred-internals.h" | ||
21 | 20 | ||
22 | #if 0 | 21 | #if 0 |
23 | #define kdebug(FMT, ...) \ | 22 | #define kdebug(FMT, ...) \ |
@@ -210,6 +209,31 @@ void exit_creds(struct task_struct *tsk) | |||
210 | } | 209 | } |
211 | } | 210 | } |
212 | 211 | ||
212 | /** | ||
213 | * get_task_cred - Get another task's objective credentials | ||
214 | * @task: The task to query | ||
215 | * | ||
216 | * Get the objective credentials of a task, pinning them so that they can't go | ||
217 | * away. Accessing a task's credentials directly is not permitted. | ||
218 | * | ||
219 | * The caller must also make sure task doesn't get deleted, either by holding a | ||
220 | * ref on task or by holding tasklist_lock to prevent it from being unlinked. | ||
221 | */ | ||
222 | const struct cred *get_task_cred(struct task_struct *task) | ||
223 | { | ||
224 | const struct cred *cred; | ||
225 | |||
226 | rcu_read_lock(); | ||
227 | |||
228 | do { | ||
229 | cred = __task_cred((task)); | ||
230 | BUG_ON(!cred); | ||
231 | } while (!atomic_inc_not_zero(&((struct cred *)cred)->usage)); | ||
232 | |||
233 | rcu_read_unlock(); | ||
234 | return cred; | ||
235 | } | ||
236 | |||
213 | /* | 237 | /* |
214 | * Allocate blank credentials, such that the credentials can be filled in at a | 238 | * Allocate blank credentials, such that the credentials can be filled in at a |
215 | * later date without risk of ENOMEM. | 239 | * later date without risk of ENOMEM. |
@@ -348,66 +372,6 @@ struct cred *prepare_exec_creds(void) | |||
348 | } | 372 | } |
349 | 373 | ||
350 | /* | 374 | /* |
351 | * prepare new credentials for the usermode helper dispatcher | ||
352 | */ | ||
353 | struct cred *prepare_usermodehelper_creds(void) | ||
354 | { | ||
355 | #ifdef CONFIG_KEYS | ||
356 | struct thread_group_cred *tgcred = NULL; | ||
357 | #endif | ||
358 | struct cred *new; | ||
359 | |||
360 | #ifdef CONFIG_KEYS | ||
361 | tgcred = kzalloc(sizeof(*new->tgcred), GFP_ATOMIC); | ||
362 | if (!tgcred) | ||
363 | return NULL; | ||
364 | #endif | ||
365 | |||
366 | new = kmem_cache_alloc(cred_jar, GFP_ATOMIC); | ||
367 | if (!new) | ||
368 | goto free_tgcred; | ||
369 | |||
370 | kdebug("prepare_usermodehelper_creds() alloc %p", new); | ||
371 | |||
372 | memcpy(new, &init_cred, sizeof(struct cred)); | ||
373 | |||
374 | atomic_set(&new->usage, 1); | ||
375 | set_cred_subscribers(new, 0); | ||
376 | get_group_info(new->group_info); | ||
377 | get_uid(new->user); | ||
378 | |||
379 | #ifdef CONFIG_KEYS | ||
380 | new->thread_keyring = NULL; | ||
381 | new->request_key_auth = NULL; | ||
382 | new->jit_keyring = KEY_REQKEY_DEFL_DEFAULT; | ||
383 | |||
384 | atomic_set(&tgcred->usage, 1); | ||
385 | spin_lock_init(&tgcred->lock); | ||
386 | new->tgcred = tgcred; | ||
387 | #endif | ||
388 | |||
389 | #ifdef CONFIG_SECURITY | ||
390 | new->security = NULL; | ||
391 | #endif | ||
392 | if (security_prepare_creds(new, &init_cred, GFP_ATOMIC) < 0) | ||
393 | goto error; | ||
394 | validate_creds(new); | ||
395 | |||
396 | BUG_ON(atomic_read(&new->usage) != 1); | ||
397 | return new; | ||
398 | |||
399 | error: | ||
400 | put_cred(new); | ||
401 | return NULL; | ||
402 | |||
403 | free_tgcred: | ||
404 | #ifdef CONFIG_KEYS | ||
405 | kfree(tgcred); | ||
406 | #endif | ||
407 | return NULL; | ||
408 | } | ||
409 | |||
410 | /* | ||
411 | * Copy credentials for the new process created by fork() | 375 | * Copy credentials for the new process created by fork() |
412 | * | 376 | * |
413 | * We share if we can, but under some circumstances we have to generate a new | 377 | * We share if we can, but under some circumstances we have to generate a new |
@@ -523,8 +487,6 @@ int commit_creds(struct cred *new) | |||
523 | #endif | 487 | #endif |
524 | BUG_ON(atomic_read(&new->usage) < 1); | 488 | BUG_ON(atomic_read(&new->usage) < 1); |
525 | 489 | ||
526 | security_commit_creds(new, old); | ||
527 | |||
528 | get_cred(new); /* we will require a ref for the subj creds too */ | 490 | get_cred(new); /* we will require a ref for the subj creds too */ |
529 | 491 | ||
530 | /* dumpability changes */ | 492 | /* dumpability changes */ |
@@ -560,8 +522,6 @@ int commit_creds(struct cred *new) | |||
560 | atomic_dec(&old->user->processes); | 522 | atomic_dec(&old->user->processes); |
561 | alter_cred_subscribers(old, -2); | 523 | alter_cred_subscribers(old, -2); |
562 | 524 | ||
563 | sched_switch_user(task); | ||
564 | |||
565 | /* send notifications */ | 525 | /* send notifications */ |
566 | if (new->uid != old->uid || | 526 | if (new->uid != old->uid || |
567 | new->euid != old->euid || | 527 | new->euid != old->euid || |