aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/cred.c113
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 */
484struct 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
519error:
520 put_cred(new);
521 return NULL;
522}
523EXPORT_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 */
533int set_security_override(struct cred *new, u32 secid)
534{
535 return security_kernel_act_as(new, secid);
536}
537EXPORT_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 */
549int 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}
560EXPORT_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 */
571int 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}
577EXPORT_SYMBOL(set_create_files_as);