Skip to content

Commit

Permalink
LSM: Use lsmblob in security_cred_getsecid
Browse files Browse the repository at this point in the history
Change the security_cred_getsecid() interface to fill in a
lsmblob instead of a u32 secid. The associated data elements
in the audit sub-system are changed from a secid to a lsmblob
to accommodate multiple possible LSM audit users.

Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: John Johansen <john.johansen@canonical.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Cc: linux-integrity@vger.kernel.org
Cc: linux-audit@redhat.com
  • Loading branch information
cschaufler authored and intel-lab-lkp committed Jul 22, 2021
1 parent 457edf1 commit 7a5105a
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 48 deletions.
2 changes: 1 addition & 1 deletion include/linux/security.h
Expand Up @@ -481,7 +481,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);
void security_cred_getsecid(const struct cred *c, struct lsmblob *blob);
int security_kernel_act_as(struct cred *new, struct lsmblob *blob);
int security_kernel_create_files_as(struct cred *new, struct inode *inode);
int security_kernel_module_request(char *kmod_name);
Expand Down
25 changes: 7 additions & 18 deletions kernel/audit.c
Expand Up @@ -125,7 +125,7 @@ static u32 audit_backlog_wait_time = AUDIT_BACKLOG_WAIT_TIME;
/* The identity of the user shutting down the audit system. */
static kuid_t audit_sig_uid = INVALID_UID;
static pid_t audit_sig_pid = -1;
static u32 audit_sig_sid;
struct lsmblob audit_sig_lsm;

/* Records can be lost in several ways:
0) [suppressed in audit_alloc]
Expand Down Expand Up @@ -1441,29 +1441,21 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
}
case AUDIT_SIGNAL_INFO:
len = 0;
if (audit_sig_sid) {
struct lsmblob blob;

/*
* lsmblob_init sets all values in the lsmblob
* to audit_sig_sid. This is temporary until
* audit_sig_sid is converted to a lsmblob, which
* happens later in this patch set.
*/
lsmblob_init(&blob, audit_sig_sid);
err = security_secid_to_secctx(&blob, &ctx, &len);
if (lsmblob_is_set(&audit_sig_lsm)) {
err = security_secid_to_secctx(&audit_sig_lsm, &ctx,
&len);
if (err)
return err;
}
sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL);
if (!sig_data) {
if (audit_sig_sid)
if (lsmblob_is_set(&audit_sig_lsm))
security_release_secctx(ctx, len);
return -ENOMEM;
}
sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid);
sig_data->pid = audit_sig_pid;
if (audit_sig_sid) {
if (lsmblob_is_set(&audit_sig_lsm)) {
memcpy(sig_data->ctx, ctx, len);
security_release_secctx(ctx, len);
}
Expand Down Expand Up @@ -2352,7 +2344,6 @@ int audit_set_loginuid(kuid_t loginuid)
int audit_signal_info(int sig, struct task_struct *t)
{
kuid_t uid = current_uid(), auid;
struct lsmblob blob;

if (auditd_test_task(t) &&
(sig == SIGTERM || sig == SIGHUP ||
Expand All @@ -2363,9 +2354,7 @@ int audit_signal_info(int sig, struct task_struct *t)
audit_sig_uid = auid;
else
audit_sig_uid = uid;
security_task_getsecid_subj(current, &blob);
/* scaffolding until audit_sig_sid is converted */
audit_sig_sid = blob.secid[0];
security_task_getsecid_subj(current, &audit_sig_lsm);
}

return audit_signal_info_syscall(t);
Expand Down
3 changes: 2 additions & 1 deletion kernel/audit.h
Expand Up @@ -12,6 +12,7 @@
#include <linux/fs.h>
#include <linux/audit.h>
#include <linux/skbuff.h>
#include <linux/security.h>
#include <uapi/linux/mqueue.h>
#include <linux/tty.h>

Expand Down Expand Up @@ -137,7 +138,7 @@ struct audit_context {
kuid_t target_auid;
kuid_t target_uid;
unsigned int target_sessionid;
u32 target_sid;
struct lsmblob target_lsm;
char target_comm[TASK_COMM_LEN];

struct audit_tree_refs *trees, *first_trees;
Expand Down
33 changes: 12 additions & 21 deletions kernel/auditsc.c
Expand Up @@ -111,7 +111,7 @@ struct audit_aux_data_pids {
kuid_t target_auid[AUDIT_AUX_PIDS];
kuid_t target_uid[AUDIT_AUX_PIDS];
unsigned int target_sessionid[AUDIT_AUX_PIDS];
u32 target_sid[AUDIT_AUX_PIDS];
struct lsmblob target_lsm[AUDIT_AUX_PIDS];
char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
int pid_count;
};
Expand Down Expand Up @@ -997,14 +997,14 @@ static inline void audit_free_context(struct audit_context *context)
}

static int audit_log_pid_context(struct audit_context *context, pid_t pid,
kuid_t auid, kuid_t uid, unsigned int sessionid,
u32 sid, char *comm)
kuid_t auid, kuid_t uid,
unsigned int sessionid,
struct lsmblob *blob, char *comm)
{
struct audit_buffer *ab;
char *ctx = NULL;
u32 len;
int rc = 0;
struct lsmblob blob;

ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
if (!ab)
Expand All @@ -1013,9 +1013,8 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid,
from_kuid(&init_user_ns, auid),
from_kuid(&init_user_ns, uid), sessionid);
if (sid) {
lsmblob_init(&blob, sid);
if (security_secid_to_secctx(&blob, &ctx, &len)) {
if (lsmblob_is_set(blob)) {
if (security_secid_to_secctx(blob, &ctx, &len)) {
audit_log_format(ab, " obj=(none)");
rc = 1;
} else {
Expand Down Expand Up @@ -1590,7 +1589,7 @@ static void audit_log_exit(void)
axs->target_auid[i],
axs->target_uid[i],
axs->target_sessionid[i],
axs->target_sid[i],
&axs->target_lsm[i],
axs->target_comm[i]))
call_panic = 1;
}
Expand All @@ -1599,7 +1598,7 @@ static void audit_log_exit(void)
audit_log_pid_context(context, context->target_pid,
context->target_auid, context->target_uid,
context->target_sessionid,
context->target_sid, context->target_comm))
&context->target_lsm, context->target_comm))
call_panic = 1;

if (context->pwd.dentry && context->pwd.mnt) {
Expand Down Expand Up @@ -1775,7 +1774,7 @@ void __audit_syscall_exit(int success, long return_code)
context->aux = NULL;
context->aux_pids = NULL;
context->target_pid = 0;
context->target_sid = 0;
lsmblob_init(&context->target_lsm, 0);
context->sockaddr_len = 0;
context->type = 0;
context->fds[0] = -1;
Expand Down Expand Up @@ -2434,15 +2433,12 @@ int __audit_sockaddr(int len, void *a)
void __audit_ptrace(struct task_struct *t)
{
struct audit_context *context = audit_context();
struct lsmblob blob;

context->target_pid = task_tgid_nr(t);
context->target_auid = audit_get_loginuid(t);
context->target_uid = task_uid(t);
context->target_sessionid = audit_get_sessionid(t);
security_task_getsecid_obj(t, &blob);
/* scaffolding - until target_sid is converted */
context->target_sid = blob.secid[0];
security_task_getsecid_obj(t, &context->target_lsm);
memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
}

Expand All @@ -2458,7 +2454,6 @@ int audit_signal_info_syscall(struct task_struct *t)
struct audit_aux_data_pids *axp;
struct audit_context *ctx = audit_context();
kuid_t t_uid = task_uid(t);
struct lsmblob blob;

if (!audit_signals || audit_dummy_context())
return 0;
Expand All @@ -2470,9 +2465,7 @@ int audit_signal_info_syscall(struct task_struct *t)
ctx->target_auid = audit_get_loginuid(t);
ctx->target_uid = t_uid;
ctx->target_sessionid = audit_get_sessionid(t);
security_task_getsecid_obj(t, &blob);
/* scaffolding until target_sid is converted */
ctx->target_sid = blob.secid[0];
security_task_getsecid_obj(t, &ctx->target_lsm);
memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
return 0;
}
Expand All @@ -2493,9 +2486,7 @@ int audit_signal_info_syscall(struct task_struct *t)
axp->target_auid[axp->pid_count] = audit_get_loginuid(t);
axp->target_uid[axp->pid_count] = t_uid;
axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t);
security_task_getsecid_obj(t, &blob);
/* scaffolding until target_sid is converted */
axp->target_sid[axp->pid_count] = blob.secid[0];
security_task_getsecid_obj(t, &axp->target_lsm[axp->pid_count]);
memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
axp->pid_count++;

Expand Down
8 changes: 4 additions & 4 deletions security/integrity/ima/ima_main.c
Expand Up @@ -470,7 +470,6 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot)
int ima_bprm_check(struct linux_binprm *bprm)
{
int ret;
u32 secid;
struct lsmblob blob;

security_task_getsecid_subj(current, &blob);
Expand All @@ -480,9 +479,10 @@ int ima_bprm_check(struct linux_binprm *bprm)
if (ret)
return ret;

security_cred_getsecid(bprm->cred, &secid);
return process_measurement(bprm->file, bprm->cred, secid, NULL, 0,
MAY_EXEC, CREDS_CHECK);
security_cred_getsecid(bprm->cred, &blob);
/* scaffolding until process_measurement changes */
return process_measurement(bprm->file, bprm->cred, blob.secid[0],
NULL, 0, MAY_EXEC, CREDS_CHECK);
}

/**
Expand Down
12 changes: 9 additions & 3 deletions security/security.c
Expand Up @@ -1798,10 +1798,16 @@ 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)
void security_cred_getsecid(const struct cred *c, struct lsmblob *blob)
{
*secid = 0;
call_void_hook(cred_getsecid, c, secid);
struct security_hook_list *hp;

lsmblob_init(blob, 0);
hlist_for_each_entry(hp, &security_hook_heads.cred_getsecid, list) {
if (WARN_ON(hp->lsmid->slot < 0 || hp->lsmid->slot >= lsm_slot))
continue;
hp->hook.cred_getsecid(c, &blob->secid[hp->lsmid->slot]);
}
}
EXPORT_SYMBOL(security_cred_getsecid);

Expand Down

0 comments on commit 7a5105a

Please sign in to comment.