Skip to content

Commit

Permalink
security: Add a cred_getsecid hook
Browse files Browse the repository at this point in the history
For IMA purposes, we want to be able to obtain the prepared secid in the
bprm structure before the credentials are committed. Add a cred_getsecid
hook that makes this possible.

Signed-off-by: Matthew Garrett <mjg59@google.com>
Acked-by: Paul Moore <paul@paul-moore.com>
Cc: Paul Moore <paul@paul-moore.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Casey Schaufler <casey@schaufler-ca.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
  • Loading branch information
mjg59 authored and Mimi Zohar committed Mar 23, 2018
1 parent 5893ed1 commit 3ec3011
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/linux/lsm_hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,10 @@
* @new points to the new credentials.
* @old points to the original credentials.
* Transfer data from original creds to new creds
* @cred_getsecid:
* Retrieve the security identifier of the cred structure @c
* @c contains the credentials, secid will be placed into @secid.
* In case of failure, @secid will be set to zero.
* @kernel_act_as:
* Set the credentials for a kernel service to act as (subjective context).
* @new points to the credentials to be modified.
Expand Down Expand Up @@ -1542,6 +1546,7 @@ union security_list_options {
int (*cred_prepare)(struct cred *new, const struct cred *old,
gfp_t gfp);
void (*cred_transfer)(struct cred *new, const struct cred *old);
void (*cred_getsecid)(const struct cred *c, u32 *secid);
int (*kernel_act_as)(struct cred *new, u32 secid);
int (*kernel_create_files_as)(struct cred *new, struct inode *inode);
int (*kernel_module_request)(char *kmod_name);
Expand Down Expand Up @@ -1825,6 +1830,7 @@ struct security_hook_heads {
struct list_head cred_free;
struct list_head cred_prepare;
struct list_head cred_transfer;
struct list_head cred_getsecid;
struct list_head kernel_act_as;
struct list_head kernel_create_files_as;
struct list_head kernel_read_file;
Expand Down
1 change: 1 addition & 0 deletions include/linux/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ int security_cred_alloc_blank(struct cred *cred, gfp_t gfp);
void security_cred_free(struct cred *cred);
int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp);
void security_transfer_creds(struct cred *new, const struct cred *old);
void security_cred_getsecid(const struct cred *c, u32 *secid);
int security_kernel_act_as(struct cred *new, u32 secid);
int security_kernel_create_files_as(struct cred *new, struct inode *inode);
int security_kernel_module_request(char *kmod_name);
Expand Down
7 changes: 7 additions & 0 deletions security/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,13 @@ void security_transfer_creds(struct cred *new, const struct cred *old)
call_void_hook(cred_transfer, new, old);
}

void security_cred_getsecid(const struct cred *c, u32 *secid)
{
*secid = 0;
call_void_hook(cred_getsecid, c, secid);
}
EXPORT_SYMBOL(security_cred_getsecid);

int security_kernel_act_as(struct cred *new, u32 secid)
{
return call_int_hook(kernel_act_as, 0, new, secid);
Expand Down
6 changes: 6 additions & 0 deletions security/selinux/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -3844,6 +3844,11 @@ static void selinux_cred_transfer(struct cred *new, const struct cred *old)
*tsec = *old_tsec;
}

static void selinux_cred_getsecid(const struct cred *c, u32 *secid)
{
*secid = cred_sid(c);
}

/*
* set the security data for a kernel service
* - all the creation contexts are set to unlabelled
Expand Down Expand Up @@ -6482,6 +6487,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(cred_free, selinux_cred_free),
LSM_HOOK_INIT(cred_prepare, selinux_cred_prepare),
LSM_HOOK_INIT(cred_transfer, selinux_cred_transfer),
LSM_HOOK_INIT(cred_getsecid, selinux_cred_getsecid),
LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as),
LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as),
LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request),
Expand Down
18 changes: 18 additions & 0 deletions security/smack/smack_lsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2049,6 +2049,23 @@ static void smack_cred_transfer(struct cred *new, const struct cred *old)
/* cbs copy rule list */
}

/**
* smack_cred_getsecid - get the secid corresponding to a creds structure
* @c: the object creds
* @secid: where to put the result
*
* Sets the secid to contain a u32 version of the smack label.
*/
static void smack_cred_getsecid(const struct cred *c, u32 *secid)
{
struct smack_known *skp;

rcu_read_lock();
skp = smk_of_task(c->security);
*secid = skp->smk_secid;
rcu_read_unlock();
}

/**
* smack_kernel_act_as - Set the subjective context in a set of credentials
* @new: points to the set of credentials to be modified.
Expand Down Expand Up @@ -4733,6 +4750,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(cred_free, smack_cred_free),
LSM_HOOK_INIT(cred_prepare, smack_cred_prepare),
LSM_HOOK_INIT(cred_transfer, smack_cred_transfer),
LSM_HOOK_INIT(cred_getsecid, smack_cred_getsecid),
LSM_HOOK_INIT(kernel_act_as, smack_kernel_act_as),
LSM_HOOK_INIT(kernel_create_files_as, smack_kernel_create_files_as),
LSM_HOOK_INIT(task_setpgid, smack_task_setpgid),
Expand Down

0 comments on commit 3ec3011

Please sign in to comment.