diff options
Diffstat (limited to 'kernel/cred.c')
-rw-r--r-- | kernel/cred.c | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/kernel/cred.c b/kernel/cred.c index f3ca10660617..13697ca2bb38 100644 --- a/kernel/cred.c +++ b/kernel/cred.c | |||
@@ -462,3 +462,116 @@ void __init cred_init(void) | |||
462 | cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), | 462 | cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), |
463 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); | 463 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); |
464 | } | 464 | } |
465 | |||
466 | /** | ||
467 | * prepare_kernel_cred - Prepare a set of credentials for a kernel service | ||
468 | * @daemon: A userspace daemon to be used as a reference | ||
469 | * | ||
470 | * Prepare a set of credentials for a kernel service. This can then be used to | ||
471 | * override a task's own credentials so that work can be done on behalf of that | ||
472 | * task that requires a different subjective context. | ||
473 | * | ||
474 | * @daemon is used to provide a base for the security record, but can be NULL. | ||
475 | * If @daemon is supplied, then the security data will be derived from that; | ||
476 | * otherwise they'll be set to 0 and no groups, full capabilities and no keys. | ||
477 | * | ||
478 | * The caller may change these controls afterwards if desired. | ||
479 | * | ||
480 | * Returns the new credentials or NULL if out of memory. | ||
481 | * | ||
482 | * Does not take, and does not return holding current->cred_replace_mutex. | ||
483 | */ | ||
484 | struct cred *prepare_kernel_cred(struct task_struct *daemon) | ||
485 | { | ||
486 | const struct cred *old; | ||
487 | struct cred *new; | ||
488 | |||
489 | new = kmem_cache_alloc(cred_jar, GFP_KERNEL); | ||
490 | if (!new) | ||
491 | return NULL; | ||
492 | |||
493 | if (daemon) | ||
494 | old = get_task_cred(daemon); | ||
495 | else | ||
496 | old = get_cred(&init_cred); | ||
497 | |||
498 | get_uid(new->user); | ||
499 | get_group_info(new->group_info); | ||
500 | |||
501 | #ifdef CONFIG_KEYS | ||
502 | atomic_inc(&init_tgcred.usage); | ||
503 | new->tgcred = &init_tgcred; | ||
504 | new->request_key_auth = NULL; | ||
505 | new->thread_keyring = NULL; | ||
506 | new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; | ||
507 | #endif | ||
508 | |||
509 | #ifdef CONFIG_SECURITY | ||
510 | new->security = NULL; | ||
511 | #endif | ||
512 | if (security_prepare_creds(new, old, GFP_KERNEL) < 0) | ||
513 | goto error; | ||
514 | |||
515 | atomic_set(&new->usage, 1); | ||
516 | put_cred(old); | ||
517 | return new; | ||
518 | |||
519 | error: | ||
520 | put_cred(new); | ||
521 | return NULL; | ||
522 | } | ||
523 | EXPORT_SYMBOL(prepare_kernel_cred); | ||
524 | |||
525 | /** | ||
526 | * set_security_override - Set the security ID in a set of credentials | ||
527 | * @new: The credentials to alter | ||
528 | * @secid: The LSM security ID to set | ||
529 | * | ||
530 | * Set the LSM security ID in a set of credentials so that the subjective | ||
531 | * security is overridden when an alternative set of credentials is used. | ||
532 | */ | ||
533 | int set_security_override(struct cred *new, u32 secid) | ||
534 | { | ||
535 | return security_kernel_act_as(new, secid); | ||
536 | } | ||
537 | EXPORT_SYMBOL(set_security_override); | ||
538 | |||
539 | /** | ||
540 | * set_security_override_from_ctx - Set the security ID in a set of credentials | ||
541 | * @new: The credentials to alter | ||
542 | * @secctx: The LSM security context to generate the security ID from. | ||
543 | * | ||
544 | * Set the LSM security ID in a set of credentials so that the subjective | ||
545 | * security is overridden when an alternative set of credentials is used. The | ||
546 | * security ID is specified in string form as a security context to be | ||
547 | * interpreted by the LSM. | ||
548 | */ | ||
549 | int set_security_override_from_ctx(struct cred *new, const char *secctx) | ||
550 | { | ||
551 | u32 secid; | ||
552 | int ret; | ||
553 | |||
554 | ret = security_secctx_to_secid(secctx, strlen(secctx), &secid); | ||
555 | if (ret < 0) | ||
556 | return ret; | ||
557 | |||
558 | return set_security_override(new, secid); | ||
559 | } | ||
560 | EXPORT_SYMBOL(set_security_override_from_ctx); | ||
561 | |||
562 | /** | ||
563 | * set_create_files_as - Set the LSM file create context in a set of credentials | ||
564 | * @new: The credentials to alter | ||
565 | * @inode: The inode to take the context from | ||
566 | * | ||
567 | * Change the LSM file creation context in a set of credentials to be the same | ||
568 | * as the object context of the specified inode, so that the new inodes have | ||
569 | * the same MAC context as that inode. | ||
570 | */ | ||
571 | int set_create_files_as(struct cred *new, struct inode *inode) | ||
572 | { | ||
573 | new->fsuid = inode->i_uid; | ||
574 | new->fsgid = inode->i_gid; | ||
575 | return security_kernel_create_files_as(new, inode); | ||
576 | } | ||
577 | EXPORT_SYMBOL(set_create_files_as); | ||