diff options
author | David Howells <dhowells@redhat.com> | 2008-11-13 18:39:26 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-11-13 18:39:26 -0500 |
commit | 3b11a1decef07c19443d24ae926982bc8ec9f4c0 (patch) | |
tree | b6555f0e5b07f4b2badd332a0a900b974920c49d /kernel/fork.c | |
parent | 98870ab0a5a3f1822aee681d2997017e1c87d026 (diff) |
CRED: Differentiate objective and effective subjective credentials on a task
Differentiate the objective and real subjective credentials from the effective
subjective credentials on a task by introducing a second credentials pointer
into the task_struct.
task_struct::real_cred then refers to the objective and apparent real
subjective credentials of a task, as perceived by the other tasks in the
system.
task_struct::cred then refers to the effective subjective credentials of a
task, as used by that task when it's actually running. These are not visible
to the other tasks in the system.
__task_cred(task) then refers to the objective/real credentials of the task in
question.
current_cred() refers to the effective subjective credentials of the current
task.
prepare_creds() uses the objective creds as a base and commit_creds() changes
both pointers in the task_struct (indeed commit_creds() requires them to be the
same).
override_creds() and revert_creds() change the subjective creds pointer only,
and the former returns the old subjective creds. These are used by NFSD,
faccessat() and do_coredump(), and will by used by CacheFiles.
In SELinux, current_has_perm() is provided as an alternative to
task_has_perm(). This uses the effective subjective context of current,
whereas task_has_perm() uses the objective/real context of the subject.
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'kernel/fork.c')
-rw-r--r-- | kernel/fork.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 82a7948a664e..af0d0f04585c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -146,6 +146,7 @@ void __put_task_struct(struct task_struct *tsk) | |||
146 | WARN_ON(atomic_read(&tsk->usage)); | 146 | WARN_ON(atomic_read(&tsk->usage)); |
147 | WARN_ON(tsk == current); | 147 | WARN_ON(tsk == current); |
148 | 148 | ||
149 | put_cred(tsk->real_cred); | ||
149 | put_cred(tsk->cred); | 150 | put_cred(tsk->cred); |
150 | delayacct_tsk_free(tsk); | 151 | delayacct_tsk_free(tsk); |
151 | 152 | ||
@@ -961,10 +962,10 @@ static struct task_struct *copy_process(unsigned long clone_flags, | |||
961 | DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); | 962 | DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled); |
962 | #endif | 963 | #endif |
963 | retval = -EAGAIN; | 964 | retval = -EAGAIN; |
964 | if (atomic_read(&p->cred->user->processes) >= | 965 | if (atomic_read(&p->real_cred->user->processes) >= |
965 | p->signal->rlim[RLIMIT_NPROC].rlim_cur) { | 966 | p->signal->rlim[RLIMIT_NPROC].rlim_cur) { |
966 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && | 967 | if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE) && |
967 | p->cred->user != current->nsproxy->user_ns->root_user) | 968 | p->real_cred->user != current->nsproxy->user_ns->root_user) |
968 | goto bad_fork_free; | 969 | goto bad_fork_free; |
969 | } | 970 | } |
970 | 971 | ||
@@ -1278,6 +1279,7 @@ bad_fork_cleanup_put_domain: | |||
1278 | module_put(task_thread_info(p)->exec_domain->module); | 1279 | module_put(task_thread_info(p)->exec_domain->module); |
1279 | bad_fork_cleanup_count: | 1280 | bad_fork_cleanup_count: |
1280 | atomic_dec(&p->cred->user->processes); | 1281 | atomic_dec(&p->cred->user->processes); |
1282 | put_cred(p->real_cred); | ||
1281 | put_cred(p->cred); | 1283 | put_cred(p->cred); |
1282 | bad_fork_free: | 1284 | bad_fork_free: |
1283 | free_task(p); | 1285 | free_task(p); |