mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 03:36:19 +00:00
CRED: Detach the credentials from task_struct
Detach the credentials from task_struct, duplicating them in copy_process() and releasing them in __put_task_struct(). Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: James Morris <jmorris@namei.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
This commit is contained in:
parent
b6dff3ec5e
commit
f1752eec61
11 changed files with 179 additions and 83 deletions
|
@ -158,4 +158,33 @@ do { \
|
||||||
*(_gid) = current->cred->fsgid; \
|
*(_gid) = current->cred->fsgid; \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
extern void __put_cred(struct cred *);
|
||||||
|
extern int copy_creds(struct task_struct *, unsigned long);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_cred - Get a reference on a set of credentials
|
||||||
|
* @cred: The credentials to reference
|
||||||
|
*
|
||||||
|
* Get a reference on the specified set of credentials. The caller must
|
||||||
|
* release the reference.
|
||||||
|
*/
|
||||||
|
static inline struct cred *get_cred(struct cred *cred)
|
||||||
|
{
|
||||||
|
atomic_inc(&cred->usage);
|
||||||
|
return cred;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* put_cred - Release a reference to a set of credentials
|
||||||
|
* @cred: The credentials to release
|
||||||
|
*
|
||||||
|
* Release a reference to a set of credentials, deleting them when the last ref
|
||||||
|
* is released.
|
||||||
|
*/
|
||||||
|
static inline void put_cred(struct cred *cred)
|
||||||
|
{
|
||||||
|
if (atomic_dec_and_test(&(cred)->usage))
|
||||||
|
__put_cred(cred);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _LINUX_CRED_H */
|
#endif /* _LINUX_CRED_H */
|
||||||
|
|
|
@ -115,19 +115,6 @@ extern struct group_info init_groups;
|
||||||
|
|
||||||
extern struct cred init_cred;
|
extern struct cred init_cred;
|
||||||
|
|
||||||
#define INIT_CRED(p) \
|
|
||||||
{ \
|
|
||||||
.usage = ATOMIC_INIT(3), \
|
|
||||||
.securebits = SECUREBITS_DEFAULT, \
|
|
||||||
.cap_inheritable = CAP_INIT_INH_SET, \
|
|
||||||
.cap_permitted = CAP_FULL_SET, \
|
|
||||||
.cap_effective = CAP_INIT_EFF_SET, \
|
|
||||||
.cap_bset = CAP_INIT_BSET, \
|
|
||||||
.user = INIT_USER, \
|
|
||||||
.group_info = &init_groups, \
|
|
||||||
.lock = __SPIN_LOCK_UNLOCKED(p.lock), \
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* INIT_TASK is used to set up the first task table, touch at
|
* INIT_TASK is used to set up the first task table, touch at
|
||||||
* your own risk!. Base=0, limit=0x1fffff (=2MB)
|
* your own risk!. Base=0, limit=0x1fffff (=2MB)
|
||||||
|
@ -162,8 +149,7 @@ extern struct cred init_cred;
|
||||||
.children = LIST_HEAD_INIT(tsk.children), \
|
.children = LIST_HEAD_INIT(tsk.children), \
|
||||||
.sibling = LIST_HEAD_INIT(tsk.sibling), \
|
.sibling = LIST_HEAD_INIT(tsk.sibling), \
|
||||||
.group_leader = &tsk, \
|
.group_leader = &tsk, \
|
||||||
.__temp_cred = INIT_CRED(tsk.__temp_cred), \
|
.cred = &init_cred, \
|
||||||
.cred = &tsk.__temp_cred, \
|
|
||||||
.comm = "swapper", \
|
.comm = "swapper", \
|
||||||
.thread = INIT_THREAD, \
|
.thread = INIT_THREAD, \
|
||||||
.fs = &init_fs, \
|
.fs = &init_fs, \
|
||||||
|
|
|
@ -1151,7 +1151,6 @@ struct task_struct {
|
||||||
struct list_head cpu_timers[3];
|
struct list_head cpu_timers[3];
|
||||||
|
|
||||||
/* process credentials */
|
/* process credentials */
|
||||||
struct cred __temp_cred __deprecated; /* temporary credentials to be removed */
|
|
||||||
struct cred *cred; /* actual/objective task credentials */
|
struct cred *cred; /* actual/objective task credentials */
|
||||||
|
|
||||||
char comm[TASK_COMM_LEN]; /* executable name excluding path
|
char comm[TASK_COMM_LEN]; /* executable name excluding path
|
||||||
|
|
|
@ -593,15 +593,15 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
|
||||||
* manual page for definitions of the @clone_flags.
|
* manual page for definitions of the @clone_flags.
|
||||||
* @clone_flags contains the flags indicating what should be shared.
|
* @clone_flags contains the flags indicating what should be shared.
|
||||||
* Return 0 if permission is granted.
|
* Return 0 if permission is granted.
|
||||||
* @task_alloc_security:
|
* @cred_alloc_security:
|
||||||
* @p contains the task_struct for child process.
|
* @cred contains the cred struct for child process.
|
||||||
* Allocate and attach a security structure to the p->security field. The
|
* Allocate and attach a security structure to the cred->security field.
|
||||||
* security field is initialized to NULL when the task structure is
|
* The security field is initialized to NULL when the task structure is
|
||||||
* allocated.
|
* allocated.
|
||||||
* Return 0 if operation was successful.
|
* Return 0 if operation was successful.
|
||||||
* @task_free_security:
|
* @cred_free:
|
||||||
* @p contains the task_struct for process.
|
* @cred points to the credentials.
|
||||||
* Deallocate and clear the p->security field.
|
* Deallocate and clear the cred->security field in a set of credentials.
|
||||||
* @task_setuid:
|
* @task_setuid:
|
||||||
* Check permission before setting one or more of the user identity
|
* Check permission before setting one or more of the user identity
|
||||||
* attributes of the current process. The @flags parameter indicates
|
* attributes of the current process. The @flags parameter indicates
|
||||||
|
@ -1405,8 +1405,8 @@ struct security_operations {
|
||||||
int (*dentry_open) (struct file *file);
|
int (*dentry_open) (struct file *file);
|
||||||
|
|
||||||
int (*task_create) (unsigned long clone_flags);
|
int (*task_create) (unsigned long clone_flags);
|
||||||
int (*task_alloc_security) (struct task_struct *p);
|
int (*cred_alloc_security) (struct cred *cred);
|
||||||
void (*task_free_security) (struct task_struct *p);
|
void (*cred_free) (struct cred *cred);
|
||||||
int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags);
|
int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags);
|
||||||
int (*task_post_setuid) (uid_t old_ruid /* or fsuid */ ,
|
int (*task_post_setuid) (uid_t old_ruid /* or fsuid */ ,
|
||||||
uid_t old_euid, uid_t old_suid, int flags);
|
uid_t old_euid, uid_t old_suid, int flags);
|
||||||
|
@ -1660,8 +1660,8 @@ int security_file_send_sigiotask(struct task_struct *tsk,
|
||||||
int security_file_receive(struct file *file);
|
int security_file_receive(struct file *file);
|
||||||
int security_dentry_open(struct file *file);
|
int security_dentry_open(struct file *file);
|
||||||
int security_task_create(unsigned long clone_flags);
|
int security_task_create(unsigned long clone_flags);
|
||||||
int security_task_alloc(struct task_struct *p);
|
int security_cred_alloc(struct cred *cred);
|
||||||
void security_task_free(struct task_struct *p);
|
void security_cred_free(struct cred *cred);
|
||||||
int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags);
|
int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags);
|
||||||
int security_task_post_setuid(uid_t old_ruid, uid_t old_euid,
|
int security_task_post_setuid(uid_t old_ruid, uid_t old_euid,
|
||||||
uid_t old_suid, int flags);
|
uid_t old_suid, int flags);
|
||||||
|
@ -2181,12 +2181,12 @@ static inline int security_task_create(unsigned long clone_flags)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int security_task_alloc(struct task_struct *p)
|
static inline int security_cred_alloc(struct cred *cred)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void security_task_free(struct task_struct *p)
|
static inline void security_cred_free(struct cred *cred)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2,
|
static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2,
|
||||||
|
|
|
@ -9,7 +9,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \
|
||||||
rcupdate.o extable.o params.o posix-timers.o \
|
rcupdate.o extable.o params.o posix-timers.o \
|
||||||
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
|
kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
|
||||||
hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
|
hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
|
||||||
notifier.o ksysfs.o pm_qos_params.o sched_clock.o
|
notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o
|
||||||
|
|
||||||
CFLAGS_REMOVE_sched.o = -mno-spe
|
CFLAGS_REMOVE_sched.o = -mno-spe
|
||||||
|
|
||||||
|
|
96
kernel/cred.c
Normal file
96
kernel/cred.c
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/* Task credentials management
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
|
||||||
|
* Written by David Howells (dhowells@redhat.com)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public Licence
|
||||||
|
* as published by the Free Software Foundation; either version
|
||||||
|
* 2 of the Licence, or (at your option) any later version.
|
||||||
|
*/
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/cred.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/key.h>
|
||||||
|
#include <linux/keyctl.h>
|
||||||
|
#include <linux/init_task.h>
|
||||||
|
#include <linux/security.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The initial credentials for the initial task
|
||||||
|
*/
|
||||||
|
struct cred init_cred = {
|
||||||
|
.usage = ATOMIC_INIT(3),
|
||||||
|
.securebits = SECUREBITS_DEFAULT,
|
||||||
|
.cap_inheritable = CAP_INIT_INH_SET,
|
||||||
|
.cap_permitted = CAP_FULL_SET,
|
||||||
|
.cap_effective = CAP_INIT_EFF_SET,
|
||||||
|
.cap_bset = CAP_INIT_BSET,
|
||||||
|
.user = INIT_USER,
|
||||||
|
.group_info = &init_groups,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The RCU callback to actually dispose of a set of credentials
|
||||||
|
*/
|
||||||
|
static void put_cred_rcu(struct rcu_head *rcu)
|
||||||
|
{
|
||||||
|
struct cred *cred = container_of(rcu, struct cred, rcu);
|
||||||
|
|
||||||
|
BUG_ON(atomic_read(&cred->usage) != 0);
|
||||||
|
|
||||||
|
key_put(cred->thread_keyring);
|
||||||
|
key_put(cred->request_key_auth);
|
||||||
|
put_group_info(cred->group_info);
|
||||||
|
free_uid(cred->user);
|
||||||
|
security_cred_free(cred);
|
||||||
|
kfree(cred);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* __put_cred - Destroy a set of credentials
|
||||||
|
* @sec: The record to release
|
||||||
|
*
|
||||||
|
* Destroy a set of credentials on which no references remain.
|
||||||
|
*/
|
||||||
|
void __put_cred(struct cred *cred)
|
||||||
|
{
|
||||||
|
call_rcu(&cred->rcu, put_cred_rcu);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__put_cred);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy credentials for the new process created by fork()
|
||||||
|
*/
|
||||||
|
int copy_creds(struct task_struct *p, unsigned long clone_flags)
|
||||||
|
{
|
||||||
|
struct cred *pcred;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
pcred = kmemdup(p->cred, sizeof(*p->cred), GFP_KERNEL);
|
||||||
|
if (!pcred)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SECURITY
|
||||||
|
pcred->security = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ret = security_cred_alloc(pcred);
|
||||||
|
if (ret < 0) {
|
||||||
|
kfree(pcred);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic_set(&pcred->usage, 1);
|
||||||
|
get_group_info(pcred->group_info);
|
||||||
|
get_uid(pcred->user);
|
||||||
|
key_get(pcred->thread_keyring);
|
||||||
|
key_get(pcred->request_key_auth);
|
||||||
|
|
||||||
|
atomic_inc(&pcred->user->processes);
|
||||||
|
|
||||||
|
/* RCU assignment is unneeded here as no-one can have accessed this
|
||||||
|
* pointer yet, barring us */
|
||||||
|
p->cred = pcred;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -146,9 +146,7 @@ void __put_task_struct(struct task_struct *tsk)
|
||||||
WARN_ON(atomic_read(&tsk->usage));
|
WARN_ON(atomic_read(&tsk->usage));
|
||||||
WARN_ON(tsk == current);
|
WARN_ON(tsk == current);
|
||||||
|
|
||||||
security_task_free(tsk);
|
put_cred(tsk->cred);
|
||||||
free_uid(tsk->__temp_cred.user);
|
|
||||||
put_group_info(tsk->__temp_cred.group_info);
|
|
||||||
delayacct_tsk_free(tsk);
|
delayacct_tsk_free(tsk);
|
||||||
|
|
||||||
if (!profile_handoff_task(tsk))
|
if (!profile_handoff_task(tsk))
|
||||||
|
@ -969,7 +967,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
||||||
DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
|
DEBUG_LOCKS_WARN_ON(!p->hardirqs_enabled);
|
||||||
DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
|
DEBUG_LOCKS_WARN_ON(!p->softirqs_enabled);
|
||||||
#endif
|
#endif
|
||||||
p->cred = &p->__temp_cred;
|
|
||||||
retval = -EAGAIN;
|
retval = -EAGAIN;
|
||||||
if (atomic_read(&p->cred->user->processes) >=
|
if (atomic_read(&p->cred->user->processes) >=
|
||||||
p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
|
p->signal->rlim[RLIMIT_NPROC].rlim_cur) {
|
||||||
|
@ -978,9 +975,9 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
||||||
goto bad_fork_free;
|
goto bad_fork_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_inc(&p->cred->user->__count);
|
retval = copy_creds(p, clone_flags);
|
||||||
atomic_inc(&p->cred->user->processes);
|
if (retval < 0)
|
||||||
get_group_info(p->cred->group_info);
|
goto bad_fork_free;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If multiple threads are within copy_process(), then this check
|
* If multiple threads are within copy_process(), then this check
|
||||||
|
@ -1035,9 +1032,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
||||||
do_posix_clock_monotonic_gettime(&p->start_time);
|
do_posix_clock_monotonic_gettime(&p->start_time);
|
||||||
p->real_start_time = p->start_time;
|
p->real_start_time = p->start_time;
|
||||||
monotonic_to_bootbased(&p->real_start_time);
|
monotonic_to_bootbased(&p->real_start_time);
|
||||||
#ifdef CONFIG_SECURITY
|
|
||||||
p->cred->security = NULL;
|
|
||||||
#endif
|
|
||||||
p->io_context = NULL;
|
p->io_context = NULL;
|
||||||
p->audit_context = NULL;
|
p->audit_context = NULL;
|
||||||
cgroup_fork(p);
|
cgroup_fork(p);
|
||||||
|
@ -1082,10 +1076,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
|
||||||
/* Perform scheduler related setup. Assign this task to a CPU. */
|
/* Perform scheduler related setup. Assign this task to a CPU. */
|
||||||
sched_fork(p, clone_flags);
|
sched_fork(p, clone_flags);
|
||||||
|
|
||||||
if ((retval = security_task_alloc(p)))
|
|
||||||
goto bad_fork_cleanup_policy;
|
|
||||||
if ((retval = audit_alloc(p)))
|
if ((retval = audit_alloc(p)))
|
||||||
goto bad_fork_cleanup_security;
|
goto bad_fork_cleanup_policy;
|
||||||
/* copy all the process information */
|
/* copy all the process information */
|
||||||
if ((retval = copy_semundo(clone_flags, p)))
|
if ((retval = copy_semundo(clone_flags, p)))
|
||||||
goto bad_fork_cleanup_audit;
|
goto bad_fork_cleanup_audit;
|
||||||
|
@ -1284,8 +1276,6 @@ bad_fork_cleanup_semundo:
|
||||||
exit_sem(p);
|
exit_sem(p);
|
||||||
bad_fork_cleanup_audit:
|
bad_fork_cleanup_audit:
|
||||||
audit_free(p);
|
audit_free(p);
|
||||||
bad_fork_cleanup_security:
|
|
||||||
security_task_free(p);
|
|
||||||
bad_fork_cleanup_policy:
|
bad_fork_cleanup_policy:
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
mpol_put(p->mempolicy);
|
mpol_put(p->mempolicy);
|
||||||
|
@ -1298,9 +1288,7 @@ bad_fork_cleanup_cgroup:
|
||||||
bad_fork_cleanup_put_domain:
|
bad_fork_cleanup_put_domain:
|
||||||
module_put(task_thread_info(p)->exec_domain->module);
|
module_put(task_thread_info(p)->exec_domain->module);
|
||||||
bad_fork_cleanup_count:
|
bad_fork_cleanup_count:
|
||||||
put_group_info(p->cred->group_info);
|
put_cred(p->cred);
|
||||||
atomic_dec(&p->cred->user->processes);
|
|
||||||
free_uid(p->cred->user);
|
|
||||||
bad_fork_free:
|
bad_fork_free:
|
||||||
free_task(p);
|
free_task(p);
|
||||||
fork_out:
|
fork_out:
|
||||||
|
|
|
@ -340,12 +340,12 @@ static int cap_task_create(unsigned long clone_flags)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cap_task_alloc_security(struct task_struct *p)
|
static int cap_cred_alloc_security(struct cred *cred)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cap_task_free_security(struct task_struct *p)
|
static void cap_cred_free(struct cred *cred)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -890,8 +890,8 @@ void security_fixup_ops(struct security_operations *ops)
|
||||||
set_to_cap_if_null(ops, file_receive);
|
set_to_cap_if_null(ops, file_receive);
|
||||||
set_to_cap_if_null(ops, dentry_open);
|
set_to_cap_if_null(ops, dentry_open);
|
||||||
set_to_cap_if_null(ops, task_create);
|
set_to_cap_if_null(ops, task_create);
|
||||||
set_to_cap_if_null(ops, task_alloc_security);
|
set_to_cap_if_null(ops, cred_alloc_security);
|
||||||
set_to_cap_if_null(ops, task_free_security);
|
set_to_cap_if_null(ops, cred_free);
|
||||||
set_to_cap_if_null(ops, task_setuid);
|
set_to_cap_if_null(ops, task_setuid);
|
||||||
set_to_cap_if_null(ops, task_post_setuid);
|
set_to_cap_if_null(ops, task_post_setuid);
|
||||||
set_to_cap_if_null(ops, task_setgid);
|
set_to_cap_if_null(ops, task_setgid);
|
||||||
|
|
|
@ -616,14 +616,14 @@ int security_task_create(unsigned long clone_flags)
|
||||||
return security_ops->task_create(clone_flags);
|
return security_ops->task_create(clone_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
int security_task_alloc(struct task_struct *p)
|
int security_cred_alloc(struct cred *cred)
|
||||||
{
|
{
|
||||||
return security_ops->task_alloc_security(p);
|
return security_ops->cred_alloc_security(cred);
|
||||||
}
|
}
|
||||||
|
|
||||||
void security_task_free(struct task_struct *p)
|
void security_cred_free(struct cred *cred)
|
||||||
{
|
{
|
||||||
security_ops->task_free_security(p);
|
security_ops->cred_free(cred);
|
||||||
}
|
}
|
||||||
|
|
||||||
int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
|
int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
|
||||||
|
|
|
@ -158,7 +158,7 @@ static int selinux_secmark_enabled(void)
|
||||||
|
|
||||||
/* Allocate and free functions for each kind of security blob. */
|
/* Allocate and free functions for each kind of security blob. */
|
||||||
|
|
||||||
static int task_alloc_security(struct task_struct *task)
|
static int cred_alloc_security(struct cred *cred)
|
||||||
{
|
{
|
||||||
struct task_security_struct *tsec;
|
struct task_security_struct *tsec;
|
||||||
|
|
||||||
|
@ -167,18 +167,11 @@ static int task_alloc_security(struct task_struct *task)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
tsec->osid = tsec->sid = SECINITSID_UNLABELED;
|
tsec->osid = tsec->sid = SECINITSID_UNLABELED;
|
||||||
task->cred->security = tsec;
|
cred->security = tsec;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void task_free_security(struct task_struct *task)
|
|
||||||
{
|
|
||||||
struct task_security_struct *tsec = task->cred->security;
|
|
||||||
task->cred->security = NULL;
|
|
||||||
kfree(tsec);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int inode_alloc_security(struct inode *inode)
|
static int inode_alloc_security(struct inode *inode)
|
||||||
{
|
{
|
||||||
struct task_security_struct *tsec = current->cred->security;
|
struct task_security_struct *tsec = current->cred->security;
|
||||||
|
@ -3184,17 +3177,17 @@ static int selinux_task_create(unsigned long clone_flags)
|
||||||
return task_has_perm(current, current, PROCESS__FORK);
|
return task_has_perm(current, current, PROCESS__FORK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selinux_task_alloc_security(struct task_struct *tsk)
|
static int selinux_cred_alloc_security(struct cred *cred)
|
||||||
{
|
{
|
||||||
struct task_security_struct *tsec1, *tsec2;
|
struct task_security_struct *tsec1, *tsec2;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
tsec1 = current->cred->security;
|
tsec1 = current->cred->security;
|
||||||
|
|
||||||
rc = task_alloc_security(tsk);
|
rc = cred_alloc_security(cred);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
tsec2 = tsk->cred->security;
|
tsec2 = cred->security;
|
||||||
|
|
||||||
tsec2->osid = tsec1->osid;
|
tsec2->osid = tsec1->osid;
|
||||||
tsec2->sid = tsec1->sid;
|
tsec2->sid = tsec1->sid;
|
||||||
|
@ -3208,9 +3201,14 @@ static int selinux_task_alloc_security(struct task_struct *tsk)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void selinux_task_free_security(struct task_struct *tsk)
|
/*
|
||||||
|
* detach and free the LSM part of a set of credentials
|
||||||
|
*/
|
||||||
|
static void selinux_cred_free(struct cred *cred)
|
||||||
{
|
{
|
||||||
task_free_security(tsk);
|
struct task_security_struct *tsec = cred->security;
|
||||||
|
cred->security = NULL;
|
||||||
|
kfree(tsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int selinux_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
|
static int selinux_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags)
|
||||||
|
@ -5552,8 +5550,8 @@ static struct security_operations selinux_ops = {
|
||||||
.dentry_open = selinux_dentry_open,
|
.dentry_open = selinux_dentry_open,
|
||||||
|
|
||||||
.task_create = selinux_task_create,
|
.task_create = selinux_task_create,
|
||||||
.task_alloc_security = selinux_task_alloc_security,
|
.cred_alloc_security = selinux_cred_alloc_security,
|
||||||
.task_free_security = selinux_task_free_security,
|
.cred_free = selinux_cred_free,
|
||||||
.task_setuid = selinux_task_setuid,
|
.task_setuid = selinux_task_setuid,
|
||||||
.task_post_setuid = selinux_task_post_setuid,
|
.task_post_setuid = selinux_task_post_setuid,
|
||||||
.task_setgid = selinux_task_setgid,
|
.task_setgid = selinux_task_setgid,
|
||||||
|
@ -5683,7 +5681,7 @@ static __init int selinux_init(void)
|
||||||
printk(KERN_INFO "SELinux: Initializing.\n");
|
printk(KERN_INFO "SELinux: Initializing.\n");
|
||||||
|
|
||||||
/* Set the security state for the initial task. */
|
/* Set the security state for the initial task. */
|
||||||
if (task_alloc_security(current))
|
if (cred_alloc_security(current->cred))
|
||||||
panic("SELinux: Failed to initialize initial task.\n");
|
panic("SELinux: Failed to initialize initial task.\n");
|
||||||
tsec = current->cred->security;
|
tsec = current->cred->security;
|
||||||
tsec->osid = tsec->sid = SECINITSID_KERNEL;
|
tsec->osid = tsec->sid = SECINITSID_KERNEL;
|
||||||
|
|
|
@ -975,8 +975,8 @@ static int smack_file_receive(struct file *file)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* smack_task_alloc_security - "allocate" a task blob
|
* smack_cred_alloc_security - "allocate" a task cred blob
|
||||||
* @tsk: the task in need of a blob
|
* @cred: the task creds in need of a blob
|
||||||
*
|
*
|
||||||
* Smack isn't using copies of blobs. Everyone
|
* Smack isn't using copies of blobs. Everyone
|
||||||
* points to an immutable list. No alloc required.
|
* points to an immutable list. No alloc required.
|
||||||
|
@ -984,24 +984,24 @@ static int smack_file_receive(struct file *file)
|
||||||
*
|
*
|
||||||
* Always returns 0
|
* Always returns 0
|
||||||
*/
|
*/
|
||||||
static int smack_task_alloc_security(struct task_struct *tsk)
|
static int smack_cred_alloc_security(struct cred *cred)
|
||||||
{
|
{
|
||||||
tsk->cred->security = current->cred->security;
|
cred->security = current->cred->security;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* smack_task_free_security - "free" a task blob
|
* smack_cred_free - "free" task-level security credentials
|
||||||
* @task: the task with the blob
|
* @cred: the credentials in question
|
||||||
*
|
*
|
||||||
* Smack isn't using copies of blobs. Everyone
|
* Smack isn't using copies of blobs. Everyone
|
||||||
* points to an immutable list. The blobs never go away.
|
* points to an immutable list. The blobs never go away.
|
||||||
* There is no leak here.
|
* There is no leak here.
|
||||||
*/
|
*/
|
||||||
static void smack_task_free_security(struct task_struct *task)
|
static void smack_cred_free(struct cred *cred)
|
||||||
{
|
{
|
||||||
task->cred->security = NULL;
|
cred->security = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2630,8 +2630,8 @@ struct security_operations smack_ops = {
|
||||||
.file_send_sigiotask = smack_file_send_sigiotask,
|
.file_send_sigiotask = smack_file_send_sigiotask,
|
||||||
.file_receive = smack_file_receive,
|
.file_receive = smack_file_receive,
|
||||||
|
|
||||||
.task_alloc_security = smack_task_alloc_security,
|
.cred_alloc_security = smack_cred_alloc_security,
|
||||||
.task_free_security = smack_task_free_security,
|
.cred_free = smack_cred_free,
|
||||||
.task_post_setuid = cap_task_post_setuid,
|
.task_post_setuid = cap_task_post_setuid,
|
||||||
.task_setpgid = smack_task_setpgid,
|
.task_setpgid = smack_task_setpgid,
|
||||||
.task_getpgid = smack_task_getpgid,
|
.task_getpgid = smack_task_getpgid,
|
||||||
|
|
Loading…
Reference in a new issue