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;
};
{
const struct cred *cred;
int i, need_sid = 1;
- u32 sid;
+ struct lsmblob blob = { };
unsigned int sessionid;
cred = rcu_dereference_check(tsk->cred, tsk == current || task_creation);
match for now to avoid losing information that
may be wanted. An error message will also be
logged upon error */
- if (f->lsm_rule) {
+ if (f->lsm_isset) {
if (need_sid) {
- security_task_getsecid(tsk, &sid);
+ security_task_getsecid(tsk, &blob);
need_sid = 0;
}
- result = security_audit_rule_match(sid, f->type,
+ result = security_audit_rule_match(&blob,
+ f->type,
f->op,
- f->lsm_rule);
+ f->lsm_rules);
}
break;
case AUDIT_OBJ_USER:
case AUDIT_OBJ_LEV_HIGH:
/* The above note for AUDIT_SUBJ_USER...AUDIT_SUBJ_CLR
also applies here */
- if (f->lsm_rule) {
+ if (f->lsm_isset) {
/* Find files that match */
if (name) {
result = security_audit_rule_match(
- name->osid,
+ &blob,
f->type,
f->op,
- f->lsm_rule);
+ f->lsm_rules);
} else if (ctx) {
list_for_each_entry(n, &ctx->names_list, list) {
if (security_audit_rule_match(
- n->osid,
+ &blob,
f->type,
f->op,
- f->lsm_rule)) {
+ f->lsm_rules)) {
++result;
break;
}
/* Find ipc objects that match */
if (!ctx || ctx->type != AUDIT_IPC)
break;
- if (security_audit_rule_match(ctx->ipc.osid,
+ if (security_audit_rule_match(&ctx->ipc.oblob,
f->type, f->op,
- f->lsm_rule))
+ f->lsm_rules))
++result;
}
break;
return 0; /* Return if not auditing. */
state = audit_filter_task(tsk, &key);
- if (state == AUDIT_DISABLED) {
+ if (!lsm_multiple_contexts() && state == AUDIT_DISABLED) {
clear_task_syscall_work(tsk, SYSCALL_AUDIT);
return 0;
}
+ if (state == AUDIT_DISABLED)
+ clear_task_syscall_work(tsk, SYSCALL_AUDIT);
if (!(context = audit_alloc_context(state))) {
kfree(key);
}
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;
ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_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) {
- if (security_secid_to_secctx(sid, &ctx, &len)) {
- audit_log_format(ab, " obj=(none)");
- rc = 1;
- } else {
- audit_log_format(ab, " obj=%s", ctx);
- security_release_secctx(ctx, len);
- }
- }
+ rc = audit_log_object_context(ab, blob);
audit_log_format(ab, " ocomm=");
audit_log_untrustedstring(ab, comm);
audit_log_end(ab);
context->socketcall.args[i]);
break; }
case AUDIT_IPC: {
- u32 osid = context->ipc.osid;
+ struct lsmblob *oblob = &context->ipc.oblob;
audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho",
from_kuid(&init_user_ns, context->ipc.uid),
from_kgid(&init_user_ns, context->ipc.gid),
context->ipc.mode);
- if (osid) {
- char *ctx = NULL;
- u32 len;
- if (security_secid_to_secctx(osid, &ctx, &len)) {
- audit_log_format(ab, " osid=%u", osid);
- *call_panic = 1;
- } else {
- audit_log_format(ab, " obj=%s", ctx);
- security_release_secctx(ctx, len);
- }
- }
+ if (audit_log_object_context(ab, oblob))
+ *call_panic = 1;
if (context->ipc.has_perm) {
audit_log_end(ab);
ab = audit_log_start(context, GFP_KERNEL,
from_kgid(&init_user_ns, n->gid),
MAJOR(n->rdev),
MINOR(n->rdev));
- if (n->osid != 0) {
- char *ctx = NULL;
- u32 len;
-
- if (security_secid_to_secctx(
- n->osid, &ctx, &len)) {
- audit_log_format(ab, " osid=%u", n->osid);
- if (call_panic)
- *call_panic = 2;
- } else {
- audit_log_format(ab, " obj=%s", ctx);
- security_release_secctx(ctx, len);
- }
- }
+ if (audit_log_object_context(ab, &n->oblob) && call_panic)
+ *call_panic = 2;
/* log the audit_names record type */
switch (n->type) {
audit_log_end(ab);
}
+void audit_log_lsm(struct lsmblob *blob, bool exiting)
+{
+ struct audit_context *context = audit_context();
+ struct lsmcontext lsmdata;
+ struct audit_buffer *ab;
+ struct lsmblob localblob;
+ bool sep = false;
+ int error;
+ int i;
+
+ if (!lsm_multiple_contexts())
+ return;
+
+ if (context && context->in_syscall && !exiting)
+ return;
+
+ ab = audit_log_start(context, GFP_ATOMIC, AUDIT_MAC_TASK_CONTEXTS);
+ if (!ab)
+ return; /* audit_panic or being filtered */
+
+ if (blob == NULL) {
+ security_task_getsecid(current, &localblob);
+ if (!lsmblob_is_set(&localblob))
+ return;
+ blob = &localblob;
+ }
+
+ for (i = 0; i < LSMBLOB_ENTRIES; i++) {
+ if (blob->secid[i] == 0)
+ continue;
+ error = security_secid_to_secctx(blob, &lsmdata, i);
+ if (error && error != -EINVAL) {
+ audit_panic("error in audit_log_lsm");
+ return;
+ }
+
+ audit_log_format(ab, "%ssubj_%s=%s", sep ? " " : "",
+ security_lsm_slot_name(i), lsmdata.context);
+ sep = true;
+
+ security_release_secctx(&lsmdata);
+ }
+
+ audit_log_end(ab);
+}
+
static void audit_log_exit(void)
{
int i, call_panic = 0;
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;
}
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) {
}
audit_log_proctitle();
+ audit_log_lsm(NULL, true);
/* Send end of event record to help user space know we are finished */
ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE);
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;
name->uid = inode->i_uid;
name->gid = inode->i_gid;
name->rdev = inode->i_rdev;
- security_inode_getsecid(inode, &name->osid);
+ security_inode_getsecid(inode, &name->oblob);
if (flags & AUDIT_INODE_NOEVAL) {
name->fcap_ver = -1;
return;
}
EXPORT_SYMBOL_GPL(__audit_inode_child);
+/**
+ * audit_stamp_context - set the timestamp+serial in an audit context
+ * @ctx: audit_context to set
+ */
+void audit_stamp_context(struct audit_context *ctx)
+{
+ /* ctx will be NULL unless lsm_multiple_contexts() is true */
+ if (!ctx)
+ return;
+
+ ktime_get_coarse_real_ts64(&ctx->ctime);
+ ctx->serial = audit_serial();
+ ctx->current_state = AUDIT_BUILD_CONTEXT;
+}
+
/**
* auditsc_get_stamp - get local copies of audit_context values
* @ctx: audit_context for the task
int auditsc_get_stamp(struct audit_context *ctx,
struct timespec64 *t, unsigned int *serial)
{
+ if (ctx->serial && !ctx->in_syscall) {
+ t->tv_sec = ctx->ctime.tv_sec;
+ t->tv_nsec = ctx->ctime.tv_nsec;
+ *serial = ctx->serial;
+ return 1;
+ }
if (!ctx->in_syscall)
return 0;
if (!ctx->serial)
context->ipc.gid = ipcp->gid;
context->ipc.mode = ipcp->mode;
context->ipc.has_perm = 0;
- security_ipc_getsecid(ipcp, &context->ipc.osid);
+ security_ipc_getsecid(ipcp, &context->ipc.oblob);
context->type = AUDIT_IPC;
}
context->target_auid = audit_get_loginuid(t);
context->target_uid = task_uid(t);
context->target_sessionid = audit_get_sessionid(t);
- security_task_getsecid(t, &context->target_sid);
+ security_task_getsecid(t, &context->target_lsm);
memcpy(context->target_comm, t->comm, TASK_COMM_LEN);
}
ctx->target_auid = audit_get_loginuid(t);
ctx->target_uid = t_uid;
ctx->target_sessionid = audit_get_sessionid(t);
- security_task_getsecid(t, &ctx->target_sid);
+ security_task_getsecid(t, &ctx->target_lsm);
memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
return 0;
}
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(t, &axp->target_sid[axp->pid_count]);
+ security_task_getsecid(t, &axp->target_lsm[axp->pid_count]);
memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN);
axp->pid_count++;
name, af, nentries, audit_nfcfgs[op].s);
audit_log_format(ab, " pid=%u", task_pid_nr(current));
- audit_log_task_context(ab); /* subj= */
+ audit_log_task_context(ab, NULL); /* subj= */
audit_log_format(ab, " comm=");
audit_log_untrustedstring(ab, get_task_comm(comm, current));
audit_log_end(ab);
from_kuid(&init_user_ns, uid),
from_kgid(&init_user_ns, gid),
sessionid);
- audit_log_task_context(ab);
+ audit_log_task_context(ab, NULL);
audit_log_format(ab, " pid=%d comm=", task_tgid_nr(current));
audit_log_untrustedstring(ab, get_task_comm(comm, current));
audit_log_d_path_exe(ab, current->mm);
if (signr == SIGQUIT) /* don't care for those */
return;
+ audit_stamp_context(audit_context());
ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_ANOM_ABEND);
if (unlikely(!ab))
return;
audit_log_task(ab);
audit_log_format(ab, " sig=%ld res=1", signr);
+ audit_log_lsm(NULL, true);
audit_log_end(ab);
}