LCOV - code coverage report
Current view: top level - kernel - cred.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 132 151 87.4 %
Date: 2015-04-12 14:34:49 Functions: 14 18 77.8 %

          Line data    Source code
       1             : /* Task credentials management - see Documentation/security/credentials.txt
       2             :  *
       3             :  * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
       4             :  * Written by David Howells (dhowells@redhat.com)
       5             :  *
       6             :  * This program is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU General Public Licence
       8             :  * as published by the Free Software Foundation; either version
       9             :  * 2 of the Licence, or (at your option) any later version.
      10             :  */
      11             : #include <linux/export.h>
      12             : #include <linux/cred.h>
      13             : #include <linux/slab.h>
      14             : #include <linux/sched.h>
      15             : #include <linux/key.h>
      16             : #include <linux/keyctl.h>
      17             : #include <linux/init_task.h>
      18             : #include <linux/security.h>
      19             : #include <linux/binfmts.h>
      20             : #include <linux/cn_proc.h>
      21             : 
      22             : #if 0
      23             : #define kdebug(FMT, ...) \
      24             :         printk("[%-5.5s%5u] "FMT"\n", current->comm, current->pid ,##__VA_ARGS__)
      25             : #else
      26             : #define kdebug(FMT, ...) \
      27             :         no_printk("[%-5.5s%5u] "FMT"\n", current->comm, current->pid ,##__VA_ARGS__)
      28             : #endif
      29             : 
      30             : static struct kmem_cache *cred_jar;
      31             : 
      32             : /*
      33             :  * The initial credentials for the initial task
      34             :  */
      35             : struct cred init_cred = {
      36             :         .usage                  = ATOMIC_INIT(4),
      37             : #ifdef CONFIG_DEBUG_CREDENTIALS
      38             :         .subscribers            = ATOMIC_INIT(2),
      39             :         .magic                  = CRED_MAGIC,
      40             : #endif
      41             :         .uid                    = GLOBAL_ROOT_UID,
      42             :         .gid                    = GLOBAL_ROOT_GID,
      43             :         .suid                   = GLOBAL_ROOT_UID,
      44             :         .sgid                   = GLOBAL_ROOT_GID,
      45             :         .euid                   = GLOBAL_ROOT_UID,
      46             :         .egid                   = GLOBAL_ROOT_GID,
      47             :         .fsuid                  = GLOBAL_ROOT_UID,
      48             :         .fsgid                  = GLOBAL_ROOT_GID,
      49             :         .securebits             = SECUREBITS_DEFAULT,
      50             :         .cap_inheritable        = CAP_EMPTY_SET,
      51             :         .cap_permitted          = CAP_FULL_SET,
      52             :         .cap_effective          = CAP_FULL_SET,
      53             :         .cap_bset               = CAP_FULL_SET,
      54             :         .user                   = INIT_USER,
      55             :         .user_ns                = &init_user_ns,
      56             :         .group_info             = &init_groups,
      57             : };
      58             : 
      59             : static inline void set_cred_subscribers(struct cred *cred, int n)
      60             : {
      61             : #ifdef CONFIG_DEBUG_CREDENTIALS
      62             :         atomic_set(&cred->subscribers, n);
      63             : #endif
      64             : }
      65             : 
      66             : static inline int read_cred_subscribers(const struct cred *cred)
      67             : {
      68             : #ifdef CONFIG_DEBUG_CREDENTIALS
      69             :         return atomic_read(&cred->subscribers);
      70             : #else
      71             :         return 0;
      72             : #endif
      73             : }
      74             : 
      75             : static inline void alter_cred_subscribers(const struct cred *_cred, int n)
      76             : {
      77             : #ifdef CONFIG_DEBUG_CREDENTIALS
      78             :         struct cred *cred = (struct cred *) _cred;
      79             : 
      80             :         atomic_add(n, &cred->subscribers);
      81             : #endif
      82             : }
      83             : 
      84             : /*
      85             :  * The RCU callback to actually dispose of a set of credentials
      86             :  */
      87       20096 : static void put_cred_rcu(struct rcu_head *rcu)
      88             : {
      89       20096 :         struct cred *cred = container_of(rcu, struct cred, rcu);
      90             : 
      91             :         kdebug("put_cred_rcu(%p)", cred);
      92             : 
      93             : #ifdef CONFIG_DEBUG_CREDENTIALS
      94             :         if (cred->magic != CRED_MAGIC_DEAD ||
      95             :             atomic_read(&cred->usage) != 0 ||
      96             :             read_cred_subscribers(cred) != 0)
      97             :                 panic("CRED: put_cred_rcu() sees %p with"
      98             :                       " mag %x, put %p, usage %d, subscr %d\n",
      99             :                       cred, cred->magic, cred->put_addr,
     100             :                       atomic_read(&cred->usage),
     101             :                       read_cred_subscribers(cred));
     102             : #else
     103       20096 :         if (atomic_read(&cred->usage) != 0)
     104           0 :                 panic("CRED: put_cred_rcu() sees %p with usage %d\n",
     105             :                       cred, atomic_read(&cred->usage));
     106             : #endif
     107             : 
     108             :         security_cred_free(cred);
     109       20096 :         key_put(cred->session_keyring);
     110       20096 :         key_put(cred->process_keyring);
     111       20096 :         key_put(cred->thread_keyring);
     112       20096 :         key_put(cred->request_key_auth);
     113       20096 :         if (cred->group_info)
     114       40192 :                 put_group_info(cred->group_info);
     115       20096 :         free_uid(cred->user);
     116             :         put_user_ns(cred->user_ns);
     117       20096 :         kmem_cache_free(cred_jar, cred);
     118       20096 : }
     119             : 
     120             : /**
     121             :  * __put_cred - Destroy a set of credentials
     122             :  * @cred: The record to release
     123             :  *
     124             :  * Destroy a set of credentials on which no references remain.
     125             :  */
     126       20096 : void __put_cred(struct cred *cred)
     127             : {
     128       20096 :         kdebug("__put_cred(%p{%d,%d})", cred,
     129             :                atomic_read(&cred->usage),
     130             :                read_cred_subscribers(cred));
     131             : 
     132       20096 :         BUG_ON(atomic_read(&cred->usage) != 0);
     133             : #ifdef CONFIG_DEBUG_CREDENTIALS
     134             :         BUG_ON(read_cred_subscribers(cred) != 0);
     135             :         cred->magic = CRED_MAGIC_DEAD;
     136             :         cred->put_addr = __builtin_return_address(0);
     137             : #endif
     138             :         BUG_ON(cred == current->cred);
     139             :         BUG_ON(cred == current->real_cred);
     140             : 
     141       20096 :         call_rcu(&cred->rcu, put_cred_rcu);
     142       20096 : }
     143             : EXPORT_SYMBOL(__put_cred);
     144             : 
     145             : /*
     146             :  * Clean up a task's credentials when it exits
     147             :  */
     148        2915 : void exit_creds(struct task_struct *tsk)
     149             : {
     150             :         struct cred *cred;
     151             : 
     152        2915 :         kdebug("exit_creds(%u,%p,%p,{%d,%d})", tsk->pid, tsk->real_cred, tsk->cred,
     153             :                atomic_read(&tsk->cred->usage),
     154             :                read_cred_subscribers(tsk->cred));
     155             : 
     156        2915 :         cred = (struct cred *) tsk->real_cred;
     157        2915 :         tsk->real_cred = NULL;
     158             :         validate_creds(cred);
     159             :         alter_cred_subscribers(cred, -1);
     160             :         put_cred(cred);
     161             : 
     162        2915 :         cred = (struct cred *) tsk->cred;
     163        2915 :         tsk->cred = NULL;
     164             :         validate_creds(cred);
     165             :         alter_cred_subscribers(cred, -1);
     166             :         put_cred(cred);
     167        2915 : }
     168             : 
     169             : /**
     170             :  * get_task_cred - Get another task's objective credentials
     171             :  * @task: The task to query
     172             :  *
     173             :  * Get the objective credentials of a task, pinning them so that they can't go
     174             :  * away.  Accessing a task's credentials directly is not permitted.
     175             :  *
     176             :  * The caller must also make sure task doesn't get deleted, either by holding a
     177             :  * ref on task or by holding tasklist_lock to prevent it from being unlinked.
     178             :  */
     179         214 : const struct cred *get_task_cred(struct task_struct *task)
     180             : {
     181             :         const struct cred *cred;
     182             : 
     183             :         rcu_read_lock();
     184             : 
     185             :         do {
     186         214 :                 cred = __task_cred((task));
     187             :                 BUG_ON(!cred);
     188         428 :         } while (!atomic_inc_not_zero(&((struct cred *)cred)->usage));
     189             : 
     190             :         rcu_read_unlock();
     191         214 :         return cred;
     192             : }
     193             : 
     194             : /*
     195             :  * Allocate blank credentials, such that the credentials can be filled in at a
     196             :  * later date without risk of ENOMEM.
     197             :  */
     198           0 : struct cred *cred_alloc_blank(void)
     199             : {
     200             :         struct cred *new;
     201             : 
     202           0 :         new = kmem_cache_zalloc(cred_jar, GFP_KERNEL);
     203           0 :         if (!new)
     204             :                 return NULL;
     205             : 
     206           0 :         atomic_set(&new->usage, 1);
     207             : #ifdef CONFIG_DEBUG_CREDENTIALS
     208             :         new->magic = CRED_MAGIC;
     209             : #endif
     210             : 
     211             :         if (security_cred_alloc_blank(new, GFP_KERNEL) < 0)
     212             :                 goto error;
     213             : 
     214           0 :         return new;
     215             : 
     216             : error:
     217             :         abort_creds(new);
     218             :         return NULL;
     219             : }
     220             : 
     221             : /**
     222             :  * prepare_creds - Prepare a new set of credentials for modification
     223             :  *
     224             :  * Prepare a new set of task credentials for modification.  A task's creds
     225             :  * shouldn't generally be modified directly, therefore this function is used to
     226             :  * prepare a new copy, which the caller then modifies and then commits by
     227             :  * calling commit_creds().
     228             :  *
     229             :  * Preparation involves making a copy of the objective creds for modification.
     230             :  *
     231             :  * Returns a pointer to the new creds-to-be if successful, NULL otherwise.
     232             :  *
     233             :  * Call commit_creds() or abort_creds() to clean up.
     234             :  */
     235       20214 : struct cred *prepare_creds(void)
     236             : {
     237       20214 :         struct task_struct *task = current;
     238             :         const struct cred *old;
     239             :         struct cred *new;
     240             : 
     241             :         validate_process_creds();
     242             : 
     243       20214 :         new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
     244       20214 :         if (!new)
     245             :                 return NULL;
     246             : 
     247             :         kdebug("prepare_creds() alloc %p", new);
     248             : 
     249       20214 :         old = task->cred;
     250       20214 :         memcpy(new, old, sizeof(struct cred));
     251             : 
     252       20214 :         atomic_set(&new->usage, 1);
     253             :         set_cred_subscribers(new, 0);
     254       20214 :         get_group_info(new->group_info);
     255       20213 :         get_uid(new->user);
     256             :         get_user_ns(new->user_ns);
     257             : 
     258             : #ifdef CONFIG_KEYS
     259       20214 :         key_get(new->session_keyring);
     260       20211 :         key_get(new->process_keyring);
     261       20211 :         key_get(new->thread_keyring);
     262       20211 :         key_get(new->request_key_auth);
     263             : #endif
     264             : 
     265             : #ifdef CONFIG_SECURITY
     266             :         new->security = NULL;
     267             : #endif
     268             : 
     269             :         if (security_prepare_creds(new, old, GFP_KERNEL) < 0)
     270             :                 goto error;
     271             :         validate_creds(new);
     272       20211 :         return new;
     273             : 
     274             : error:
     275             :         abort_creds(new);
     276             :         return NULL;
     277             : }
     278             : EXPORT_SYMBOL(prepare_creds);
     279             : 
     280             : /*
     281             :  * Prepare credentials for current to perform an execve()
     282             :  * - The caller must hold ->cred_guard_mutex
     283             :  */
     284        2247 : struct cred *prepare_exec_creds(void)
     285             : {
     286             :         struct cred *new;
     287             : 
     288        2247 :         new = prepare_creds();
     289        2247 :         if (!new)
     290             :                 return new;
     291             : 
     292             : #ifdef CONFIG_KEYS
     293             :         /* newly exec'd tasks don't get a thread keyring */
     294        2247 :         key_put(new->thread_keyring);
     295        2247 :         new->thread_keyring = NULL;
     296             : 
     297             :         /* inherit the session keyring; new process keyring */
     298        2247 :         key_put(new->process_keyring);
     299        2247 :         new->process_keyring = NULL;
     300             : #endif
     301             : 
     302        2247 :         return new;
     303             : }
     304             : 
     305             : /*
     306             :  * Copy credentials for the new process created by fork()
     307             :  *
     308             :  * We share if we can, but under some circumstances we have to generate a new
     309             :  * set.
     310             :  *
     311             :  * The new process gets the current process's subjective credentials as its
     312             :  * objective and subjective credentials
     313             :  */
     314        2993 : int copy_creds(struct task_struct *p, unsigned long clone_flags)
     315             : {
     316             :         struct cred *new;
     317             :         int ret;
     318             : 
     319        2993 :         if (
     320             : #ifdef CONFIG_KEYS
     321        5986 :                 !p->cred->thread_keyring &&
     322             : #endif
     323        2993 :                 clone_flags & CLONE_THREAD
     324             :             ) {
     325           6 :                 p->real_cred = get_cred(p->cred);
     326           6 :                 get_cred(p->cred);
     327             :                 alter_cred_subscribers(p->cred, 2);
     328           6 :                 kdebug("share_creds(%p{%d,%d})",
     329             :                        p->cred, atomic_read(&p->cred->usage),
     330             :                        read_cred_subscribers(p->cred));
     331           6 :                 atomic_inc(&p->cred->user->processes);
     332           6 :                 return 0;
     333             :         }
     334             : 
     335        2987 :         new = prepare_creds();
     336        2987 :         if (!new)
     337             :                 return -ENOMEM;
     338             : 
     339        2987 :         if (clone_flags & CLONE_NEWUSER) {
     340             :                 ret = create_user_ns(new);
     341             :                 if (ret < 0)
     342             :                         goto error_put;
     343             :         }
     344             : 
     345             : #ifdef CONFIG_KEYS
     346             :         /* new threads get their own thread keyrings if their parent already
     347             :          * had one */
     348        2987 :         if (new->thread_keyring) {
     349           0 :                 key_put(new->thread_keyring);
     350           0 :                 new->thread_keyring = NULL;
     351           0 :                 if (clone_flags & CLONE_THREAD)
     352           0 :                         install_thread_keyring_to_cred(new);
     353             :         }
     354             : 
     355             :         /* The process keyring is only shared between the threads in a process;
     356             :          * anything outside of those threads doesn't inherit.
     357             :          */
     358        2987 :         if (!(clone_flags & CLONE_THREAD)) {
     359        2987 :                 key_put(new->process_keyring);
     360        2987 :                 new->process_keyring = NULL;
     361             :         }
     362             : #endif
     363             : 
     364        2987 :         atomic_inc(&new->user->processes);
     365        2987 :         p->cred = p->real_cred = get_cred(new);
     366             :         alter_cred_subscribers(new, 2);
     367             :         validate_creds(new);
     368        2987 :         return 0;
     369             : 
     370             : error_put:
     371             :         put_cred(new);
     372             :         return ret;
     373             : }
     374             : 
     375        2969 : static bool cred_cap_issubset(const struct cred *set, const struct cred *subset)
     376             : {
     377        2969 :         const struct user_namespace *set_ns = set->user_ns;
     378        2969 :         const struct user_namespace *subset_ns = subset->user_ns;
     379             : 
     380             :         /* If the two credentials are in the same user namespace see if
     381             :          * the capabilities of subset are a subset of set.
     382             :          */
     383        2969 :         if (set_ns == subset_ns)
     384        2969 :                 return cap_issubset(subset->cap_permitted, set->cap_permitted);
     385             : 
     386             :         /* The credentials are in a different user namespaces
     387             :          * therefore one is a subset of the other only if a set is an
     388             :          * ancestor of subset and set->euid is owner of subset or one
     389             :          * of subsets ancestors.
     390             :          */
     391           0 :         for (;subset_ns != &init_user_ns; subset_ns = subset_ns->parent) {
     392           0 :                 if ((set_ns == subset_ns->parent)  &&
     393             :                     uid_eq(subset_ns->owner, set->euid))
     394             :                         return true;
     395             :         }
     396             : 
     397             :         return false;
     398             : }
     399             : 
     400             : /**
     401             :  * commit_creds - Install new credentials upon the current task
     402             :  * @new: The credentials to be assigned
     403             :  *
     404             :  * Install a new set of credentials to the current task, using RCU to replace
     405             :  * the old set.  Both the objective and the subjective credentials pointers are
     406             :  * updated.  This function may not be called if the subjective credentials are
     407             :  * in an overridden state.
     408             :  *
     409             :  * This function eats the caller's reference to the new credentials.
     410             :  *
     411             :  * Always returns 0 thus allowing this function to be tail-called at the end
     412             :  * of, say, sys_setgid().
     413             :  */
     414        3503 : int commit_creds(struct cred *new)
     415             : {
     416        3503 :         struct task_struct *task = current;
     417        3503 :         const struct cred *old = task->real_cred;
     418             : 
     419        3503 :         kdebug("commit_creds(%p{%d,%d})", new,
     420             :                atomic_read(&new->usage),
     421             :                read_cred_subscribers(new));
     422             : 
     423             :         BUG_ON(task->cred != old);
     424             : #ifdef CONFIG_DEBUG_CREDENTIALS
     425             :         BUG_ON(read_cred_subscribers(old) < 2);
     426             :         validate_creds(old);
     427             :         validate_creds(new);
     428             : #endif
     429        3503 :         BUG_ON(atomic_read(&new->usage) < 1);
     430             : 
     431             :         get_cred(new); /* we will require a ref for the subj creds too */
     432             : 
     433             :         /* dumpability changes */
     434        3503 :         if (!uid_eq(old->euid, new->euid) ||
     435        3005 :             !gid_eq(old->egid, new->egid) ||
     436        2987 :             !uid_eq(old->fsuid, new->fsuid) ||
     437        2969 :             !gid_eq(old->fsgid, new->fsgid) ||
     438        2969 :             !cred_cap_issubset(old, new)) {
     439         534 :                 if (task->mm)
     440         534 :                         set_dumpable(task->mm, suid_dumpable);
     441         534 :                 task->pdeath_signal = 0;
     442         534 :                 smp_wmb();
     443             :         }
     444             : 
     445             :         /* alter the thread keyring */
     446        3503 :         if (!uid_eq(new->fsuid, old->fsuid))
     447         207 :                 key_fsuid_changed(task);
     448        3503 :         if (!gid_eq(new->fsgid, old->fsgid))
     449         327 :                 key_fsgid_changed(task);
     450             : 
     451             :         /* do it
     452             :          * RLIMIT_NPROC limits on user->processes have already been checked
     453             :          * in set_user().
     454             :          */
     455             :         alter_cred_subscribers(new, 2);
     456        3503 :         if (new->user != old->user)
     457         117 :                 atomic_inc(&new->user->processes);
     458        3503 :         rcu_assign_pointer(task->real_cred, new);
     459        3503 :         rcu_assign_pointer(task->cred, new);
     460        3503 :         if (new->user != old->user)
     461         117 :                 atomic_dec(&old->user->processes);
     462             :         alter_cred_subscribers(old, -2);
     463             : 
     464             :         /* send notifications */
     465             :         if (!uid_eq(new->uid,   old->uid)  ||
     466             :             !uid_eq(new->euid,  old->euid) ||
     467             :             !uid_eq(new->suid,  old->suid) ||
     468             :             !uid_eq(new->fsuid, old->fsuid))
     469             :                 proc_id_connector(task, PROC_EVENT_UID);
     470             : 
     471             :         if (!gid_eq(new->gid,   old->gid)  ||
     472             :             !gid_eq(new->egid,  old->egid) ||
     473             :             !gid_eq(new->sgid,  old->sgid) ||
     474             :             !gid_eq(new->fsgid, old->fsgid))
     475             :                 proc_id_connector(task, PROC_EVENT_GID);
     476             : 
     477             :         /* release the old obj and subj refs both */
     478             :         put_cred(old);
     479             :         put_cred(old);
     480        3503 :         return 0;
     481             : }
     482             : EXPORT_SYMBOL(commit_creds);
     483             : 
     484             : /**
     485             :  * abort_creds - Discard a set of credentials and unlock the current task
     486             :  * @new: The credentials that were going to be applied
     487             :  *
     488             :  * Discard a set of credentials that were under construction and unlock the
     489             :  * current task.
     490             :  */
     491         192 : void abort_creds(struct cred *new)
     492             : {
     493         192 :         kdebug("abort_creds(%p{%d,%d})", new,
     494             :                atomic_read(&new->usage),
     495             :                read_cred_subscribers(new));
     496             : 
     497             : #ifdef CONFIG_DEBUG_CREDENTIALS
     498             :         BUG_ON(read_cred_subscribers(new) != 0);
     499             : #endif
     500         192 :         BUG_ON(atomic_read(&new->usage) < 1);
     501             :         put_cred(new);
     502         192 : }
     503             : EXPORT_SYMBOL(abort_creds);
     504             : 
     505             : /**
     506             :  * override_creds - Override the current process's subjective credentials
     507             :  * @new: The credentials to be assigned
     508             :  *
     509             :  * Install a set of temporary override subjective credentials on the current
     510             :  * process, returning the old set for later reversion.
     511             :  */
     512       13542 : const struct cred *override_creds(const struct cred *new)
     513             : {
     514       13542 :         const struct cred *old = current->cred;
     515             : 
     516       13542 :         kdebug("override_creds(%p{%d,%d})", new,
     517             :                atomic_read(&new->usage),
     518             :                read_cred_subscribers(new));
     519             : 
     520             :         validate_creds(old);
     521             :         validate_creds(new);
     522             :         get_cred(new);
     523             :         alter_cred_subscribers(new, 1);
     524       27108 :         rcu_assign_pointer(current->cred, new);
     525             :         alter_cred_subscribers(old, -1);
     526             : 
     527       13554 :         kdebug("override_creds() = %p{%d,%d}", old,
     528             :                atomic_read(&old->usage),
     529             :                read_cred_subscribers(old));
     530       13554 :         return old;
     531             : }
     532             : EXPORT_SYMBOL(override_creds);
     533             : 
     534             : /**
     535             :  * revert_creds - Revert a temporary subjective credentials override
     536             :  * @old: The credentials to be restored
     537             :  *
     538             :  * Revert a temporary set of override subjective credentials to an old set,
     539             :  * discarding the override set.
     540             :  */
     541       13554 : void revert_creds(const struct cred *old)
     542             : {
     543       13554 :         const struct cred *override = current->cred;
     544             : 
     545       13554 :         kdebug("revert_creds(%p{%d,%d})", old,
     546             :                atomic_read(&old->usage),
     547             :                read_cred_subscribers(old));
     548             : 
     549             :         validate_creds(old);
     550             :         validate_creds(override);
     551             :         alter_cred_subscribers(old, 1);
     552       27108 :         rcu_assign_pointer(current->cred, old);
     553             :         alter_cred_subscribers(override, -1);
     554             :         put_cred(override);
     555       13554 : }
     556             : EXPORT_SYMBOL(revert_creds);
     557             : 
     558             : /*
     559             :  * initialise the credentials stuff
     560             :  */
     561           1 : void __init cred_init(void)
     562             : {
     563             :         /* allocate a slab in which we can store credentials */
     564           1 :         cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred),
     565             :                                      0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL);
     566           1 : }
     567             : 
     568             : /**
     569             :  * prepare_kernel_cred - Prepare a set of credentials for a kernel service
     570             :  * @daemon: A userspace daemon to be used as a reference
     571             :  *
     572             :  * Prepare a set of credentials for a kernel service.  This can then be used to
     573             :  * override a task's own credentials so that work can be done on behalf of that
     574             :  * task that requires a different subjective context.
     575             :  *
     576             :  * @daemon is used to provide a base for the security record, but can be NULL.
     577             :  * If @daemon is supplied, then the security data will be derived from that;
     578             :  * otherwise they'll be set to 0 and no groups, full capabilities and no keys.
     579             :  *
     580             :  * The caller may change these controls afterwards if desired.
     581             :  *
     582             :  * Returns the new credentials or NULL if out of memory.
     583             :  *
     584             :  * Does not take, and does not return holding current->cred_replace_mutex.
     585             :  */
     586          24 : struct cred *prepare_kernel_cred(struct task_struct *daemon)
     587             : {
     588             :         const struct cred *old;
     589             :         struct cred *new;
     590             : 
     591          24 :         new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
     592          24 :         if (!new)
     593             :                 return NULL;
     594             : 
     595             :         kdebug("prepare_kernel_cred() alloc %p", new);
     596             : 
     597          24 :         if (daemon)
     598          22 :                 old = get_task_cred(daemon);
     599             :         else
     600             :                 old = get_cred(&init_cred);
     601             : 
     602             :         validate_creds(old);
     603             : 
     604          24 :         *new = *old;
     605          24 :         atomic_set(&new->usage, 1);
     606             :         set_cred_subscribers(new, 0);
     607          24 :         get_uid(new->user);
     608             :         get_user_ns(new->user_ns);
     609          24 :         get_group_info(new->group_info);
     610             : 
     611             : #ifdef CONFIG_KEYS
     612          24 :         new->session_keyring = NULL;
     613          24 :         new->process_keyring = NULL;
     614          24 :         new->thread_keyring = NULL;
     615          24 :         new->request_key_auth = NULL;
     616          24 :         new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
     617             : #endif
     618             : 
     619             : #ifdef CONFIG_SECURITY
     620             :         new->security = NULL;
     621             : #endif
     622             :         if (security_prepare_creds(new, old, GFP_KERNEL) < 0)
     623             :                 goto error;
     624             : 
     625             :         put_cred(old);
     626             :         validate_creds(new);
     627          24 :         return new;
     628             : 
     629             : error:
     630             :         put_cred(new);
     631             :         put_cred(old);
     632             :         return NULL;
     633             : }
     634             : EXPORT_SYMBOL(prepare_kernel_cred);
     635             : 
     636             : /**
     637             :  * set_security_override - Set the security ID in a set of credentials
     638             :  * @new: The credentials to alter
     639             :  * @secid: The LSM security ID to set
     640             :  *
     641             :  * Set the LSM security ID in a set of credentials so that the subjective
     642             :  * security is overridden when an alternative set of credentials is used.
     643             :  */
     644           0 : int set_security_override(struct cred *new, u32 secid)
     645             : {
     646           0 :         return security_kernel_act_as(new, secid);
     647             : }
     648             : EXPORT_SYMBOL(set_security_override);
     649             : 
     650             : /**
     651             :  * set_security_override_from_ctx - Set the security ID in a set of credentials
     652             :  * @new: The credentials to alter
     653             :  * @secctx: The LSM security context to generate the security ID from.
     654             :  *
     655             :  * Set the LSM security ID in a set of credentials so that the subjective
     656             :  * security is overridden when an alternative set of credentials is used.  The
     657             :  * security ID is specified in string form as a security context to be
     658             :  * interpreted by the LSM.
     659             :  */
     660           0 : int set_security_override_from_ctx(struct cred *new, const char *secctx)
     661             : {
     662             :         u32 secid;
     663             :         int ret;
     664             : 
     665             :         ret = security_secctx_to_secid(secctx, strlen(secctx), &secid);
     666             :         if (ret < 0)
     667             :                 return ret;
     668             : 
     669             :         return set_security_override(new, secid);
     670             : }
     671             : EXPORT_SYMBOL(set_security_override_from_ctx);
     672             : 
     673             : /**
     674             :  * set_create_files_as - Set the LSM file create context in a set of credentials
     675             :  * @new: The credentials to alter
     676             :  * @inode: The inode to take the context from
     677             :  *
     678             :  * Change the LSM file creation context in a set of credentials to be the same
     679             :  * as the object context of the specified inode, so that the new inodes have
     680             :  * the same MAC context as that inode.
     681             :  */
     682           0 : int set_create_files_as(struct cred *new, struct inode *inode)
     683             : {
     684           0 :         new->fsuid = inode->i_uid;
     685           0 :         new->fsgid = inode->i_gid;
     686           0 :         return security_kernel_create_files_as(new, inode);
     687             : }
     688             : EXPORT_SYMBOL(set_create_files_as);
     689             : 
     690             : #ifdef CONFIG_DEBUG_CREDENTIALS
     691             : 
     692             : bool creds_are_invalid(const struct cred *cred)
     693             : {
     694             :         if (cred->magic != CRED_MAGIC)
     695             :                 return true;
     696             : #ifdef CONFIG_SECURITY_SELINUX
     697             :         /*
     698             :          * cred->security == NULL if security_cred_alloc_blank() or
     699             :          * security_prepare_creds() returned an error.
     700             :          */
     701             :         if (selinux_is_enabled() && cred->security) {
     702             :                 if ((unsigned long) cred->security < PAGE_SIZE)
     703             :                         return true;
     704             :                 if ((*(u32 *)cred->security & 0xffffff00) ==
     705             :                     (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8))
     706             :                         return true;
     707             :         }
     708             : #endif
     709             :         return false;
     710             : }
     711             : EXPORT_SYMBOL(creds_are_invalid);
     712             : 
     713             : /*
     714             :  * dump invalid credentials
     715             :  */
     716             : static void dump_invalid_creds(const struct cred *cred, const char *label,
     717             :                                const struct task_struct *tsk)
     718             : {
     719             :         printk(KERN_ERR "CRED: %s credentials: %p %s%s%s\n",
     720             :                label, cred,
     721             :                cred == &init_cred ? "[init]" : "",
     722             :                cred == tsk->real_cred ? "[real]" : "",
     723             :                cred == tsk->cred ? "[eff]" : "");
     724             :         printk(KERN_ERR "CRED: ->magic=%x, put_addr=%p\n",
     725             :                cred->magic, cred->put_addr);
     726             :         printk(KERN_ERR "CRED: ->usage=%d, subscr=%d\n",
     727             :                atomic_read(&cred->usage),
     728             :                read_cred_subscribers(cred));
     729             :         printk(KERN_ERR "CRED: ->*uid = { %d,%d,%d,%d }\n",
     730             :                 from_kuid_munged(&init_user_ns, cred->uid),
     731             :                 from_kuid_munged(&init_user_ns, cred->euid),
     732             :                 from_kuid_munged(&init_user_ns, cred->suid),
     733             :                 from_kuid_munged(&init_user_ns, cred->fsuid));
     734             :         printk(KERN_ERR "CRED: ->*gid = { %d,%d,%d,%d }\n",
     735             :                 from_kgid_munged(&init_user_ns, cred->gid),
     736             :                 from_kgid_munged(&init_user_ns, cred->egid),
     737             :                 from_kgid_munged(&init_user_ns, cred->sgid),
     738             :                 from_kgid_munged(&init_user_ns, cred->fsgid));
     739             : #ifdef CONFIG_SECURITY
     740             :         printk(KERN_ERR "CRED: ->security is %p\n", cred->security);
     741             :         if ((unsigned long) cred->security >= PAGE_SIZE &&
     742             :             (((unsigned long) cred->security & 0xffffff00) !=
     743             :              (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8)))
     744             :                 printk(KERN_ERR "CRED: ->security {%x, %x}\n",
     745             :                        ((u32*)cred->security)[0],
     746             :                        ((u32*)cred->security)[1]);
     747             : #endif
     748             : }
     749             : 
     750             : /*
     751             :  * report use of invalid credentials
     752             :  */
     753             : void __invalid_creds(const struct cred *cred, const char *file, unsigned line)
     754             : {
     755             :         printk(KERN_ERR "CRED: Invalid credentials\n");
     756             :         printk(KERN_ERR "CRED: At %s:%u\n", file, line);
     757             :         dump_invalid_creds(cred, "Specified", current);
     758             :         BUG();
     759             : }
     760             : EXPORT_SYMBOL(__invalid_creds);
     761             : 
     762             : /*
     763             :  * check the credentials on a process
     764             :  */
     765             : void __validate_process_creds(struct task_struct *tsk,
     766             :                               const char *file, unsigned line)
     767             : {
     768             :         if (tsk->cred == tsk->real_cred) {
     769             :                 if (unlikely(read_cred_subscribers(tsk->cred) < 2 ||
     770             :                              creds_are_invalid(tsk->cred)))
     771             :                         goto invalid_creds;
     772             :         } else {
     773             :                 if (unlikely(read_cred_subscribers(tsk->real_cred) < 1 ||
     774             :                              read_cred_subscribers(tsk->cred) < 1 ||
     775             :                              creds_are_invalid(tsk->real_cred) ||
     776             :                              creds_are_invalid(tsk->cred)))
     777             :                         goto invalid_creds;
     778             :         }
     779             :         return;
     780             : 
     781             : invalid_creds:
     782             :         printk(KERN_ERR "CRED: Invalid process credentials\n");
     783             :         printk(KERN_ERR "CRED: At %s:%u\n", file, line);
     784             : 
     785             :         dump_invalid_creds(tsk->real_cred, "Real", tsk);
     786             :         if (tsk->cred != tsk->real_cred)
     787             :                 dump_invalid_creds(tsk->cred, "Effective", tsk);
     788             :         else
     789             :                 printk(KERN_ERR "CRED: Effective creds == Real creds\n");
     790             :         BUG();
     791             : }
     792             : EXPORT_SYMBOL(__validate_process_creds);
     793             : 
     794             : /*
     795             :  * check creds for do_exit()
     796             :  */
     797             : void validate_creds_for_do_exit(struct task_struct *tsk)
     798             : {
     799             :         kdebug("validate_creds_for_do_exit(%p,%p{%d,%d})",
     800             :                tsk->real_cred, tsk->cred,
     801             :                atomic_read(&tsk->cred->usage),
     802             :                read_cred_subscribers(tsk->cred));
     803             : 
     804             :         __validate_process_creds(tsk, __FILE__, __LINE__);
     805             : }
     806             : 
     807             : #endif /* CONFIG_DEBUG_CREDENTIALS */

Generated by: LCOV version 1.11