return rc;
audit_log_format(ab, "op=set %s=%u old=%u ", function_name, new, old);
audit_log_session_info(ab);
- rc = audit_log_task_context(ab);
+ rc = audit_log_task_context(ab, NULL);
if (rc)
allow_changes = 0; /* Something weird, deny request */
audit_log_format(ab, " res=%d", allow_changes);
+ audit_log_lsm(NULL, false);
audit_log_end(ab);
return rc;
}
return;
audit_log_format(*ab, "pid=%d uid=%u ", pid, uid);
audit_log_session_info(*ab);
- audit_log_task_context(*ab);
+ audit_log_task_context(*ab, NULL);
}
static inline void audit_log_user_recv_msg(struct audit_buffer **ab,
u16 msg_type)
{
- audit_log_common_recv_msg(NULL, ab, msg_type);
+ struct audit_context *context;
+
+ if (!lsm_multiple_contexts()) {
+ audit_log_common_recv_msg(NULL, ab, msg_type);
+ return;
+ }
+
+ context = audit_context();
+ if (context) {
+ if (!context->in_syscall)
+ audit_stamp_context(context);
+ audit_log_common_recv_msg(context, ab, msg_type);
+ return;
+ }
+
+ audit_alloc(current);
+ context = audit_context();
+
+ audit_log_common_recv_msg(context, ab, msg_type);
}
int is_audit_feature_set(int i)
struct audit_buffer *ab;
u16 msg_type = nlh->nlmsg_type;
struct audit_sig_info *sig_data;
- char *ctx = NULL;
- u32 len;
- struct lsmcontext scaff; /* scaffolding */
err = audit_netlink_ok(skb, msg_type);
if (err)
audit_log_n_untrustedstring(ab, str, data_len);
}
audit_log_end(ab);
+ audit_log_lsm(NULL, false);
}
break;
case AUDIT_ADD_RULE:
kfree(new);
break;
}
- case AUDIT_SIGNAL_INFO:
- len = 0;
+ case AUDIT_SIGNAL_INFO: {
+ struct lsmcontext context = { };
+ int len = 0;
+
if (lsmblob_is_set(&audit_sig_lsm)) {
- err = security_secid_to_secctx(&audit_sig_lsm, &ctx,
- &len);
+ err = security_secid_to_secctx(&audit_sig_lsm,
+ &context, LSMBLOB_FIRST);
if (err)
return err;
}
- sig_data = kmalloc(sizeof(*sig_data) + len, GFP_KERNEL);
+ sig_data = kmalloc(sizeof(*sig_data) + context.len, GFP_KERNEL);
if (!sig_data) {
- if (lsmblob_is_set(&audit_sig_lsm)) {
- lsmcontext_init(&scaff, ctx, len, 0);
- security_release_secctx(&scaff);
- }
+ if (lsmblob_is_set(&audit_sig_lsm))
+ security_release_secctx(&context);
return -ENOMEM;
}
sig_data->uid = from_kuid(&init_user_ns, audit_sig_uid);
sig_data->pid = audit_sig_pid;
if (lsmblob_is_set(&audit_sig_lsm)) {
- memcpy(sig_data->ctx, ctx, len);
- lsmcontext_init(&scaff, ctx, len, 0);
- security_release_secctx(&scaff);
+ len = context.len;
+ memcpy(sig_data->ctx, context.context, len);
+ security_release_secctx(&context);
}
audit_send_reply(skb, seq, AUDIT_SIGNAL_INFO, 0, 0,
sig_data, sizeof(*sig_data) + len);
kfree(sig_data);
break;
+ }
case AUDIT_TTY_GET: {
struct audit_tty_status s;
unsigned int t;
tty ? tty_name(tty) : "(none)",
audit_get_sessionid(current));
audit_put_tty(tty);
- 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_d_path_exe(ab, current->mm); /* exe= */
/* cancel dummy context to enable supporting records */
if (ctx)
ctx->dummy = 0;
+ if (type == AUDIT_MAC_TASK_CONTEXTS && ab->ctx &&
+ ab->ctx->serial == 0) {
+ audit_stamp_context(ab->ctx);
+ audit_get_stamp(ab->ctx, &t, &serial);
+ }
audit_log_format(ab, "audit(%llu.%03lu:%u): ",
(unsigned long long)t.tv_sec, t.tv_nsec/1000000, serial);
audit_log_format(ab, "(null)");
}
-int audit_log_task_context(struct audit_buffer *ab)
+int audit_log_task_context(struct audit_buffer *ab, struct lsmblob *blob)
{
- char *ctx = NULL;
- unsigned len;
+ int i;
int error;
- struct lsmblob blob;
- struct lsmcontext scaff; /* scaffolding */
+ struct lsmblob localblob;
+ struct lsmcontext lsmdata;
- security_task_getsecid(current, &blob);
- if (!lsmblob_is_set(&blob))
+ /*
+ * If there is more than one security module that has a
+ * subject "context" it's necessary to put the subject data
+ * into a separate record to maintain compatibility.
+ */
+ if (lsm_multiple_contexts()) {
+ audit_log_format(ab, " subj=?");
return 0;
+ }
- error = security_secid_to_secctx(&blob, &ctx, &len);
- if (error) {
- if (error != -EINVAL)
- goto error_path;
- return 0;
+ if (blob == NULL) {
+ security_task_getsecid(current, &localblob);
+ if (!lsmblob_is_set(&localblob)) {
+ audit_log_format(ab, " subj=?");
+ return 0;
+ }
+ blob = &localblob;
}
- audit_log_format(ab, " subj=%s", ctx);
- lsmcontext_init(&scaff, ctx, len, 0);
- security_release_secctx(&scaff);
- return 0;
+ 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_task_context");
+ return error;
+ }
-error_path:
- audit_panic("error in audit_log_task_context");
- return error;
+ audit_log_format(ab, " subj=%s", lsmdata.context);
+ security_release_secctx(&lsmdata);
+ break;
+ }
+
+ return 0;
}
EXPORT_SYMBOL(audit_log_task_context);
+int audit_log_object_context(struct audit_buffer *ab,
+ struct lsmblob *blob)
+{
+ int i;
+ int error;
+ bool sep = false;
+ struct lsmcontext lsmdata;
+ struct audit_buffer *lsmab = NULL;
+ struct audit_context *context = NULL;
+
+ /*
+ * If there is more than one security module that has a
+ * object "context" it's necessary to put the object data
+ * into a separate record to maintain compatibility.
+ */
+ if (lsm_multiple_contexts()) {
+ audit_log_format(ab, " obj=?");
+ context = ab->ctx;
+ if (context)
+ lsmab = audit_log_start(context, GFP_KERNEL,
+ AUDIT_MAC_OBJ_CONTEXTS);
+ }
+
+ 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_object_context");
+ return error;
+ }
+
+ if (context) {
+ audit_log_format(lsmab, "%sobj_%s=%s",
+ sep ? " " : "",
+ security_lsm_slot_name(i),
+ lsmdata.context);
+ sep = true;
+ } else
+ audit_log_format(ab, " obj=%s", lsmdata.context);
+
+ security_release_secctx(&lsmdata);
+ if (!context)
+ break;
+ }
+
+ if (context)
+ audit_log_end(lsmab);
+
+ return 0;
+}
+EXPORT_SYMBOL(audit_log_object_context);
+
void audit_log_d_path_exe(struct audit_buffer *ab,
struct mm_struct *mm)
{
audit_log_format(ab, " comm=");
audit_log_untrustedstring(ab, get_task_comm(comm, current));
audit_log_d_path_exe(ab, current->mm);
- audit_log_task_context(ab);
+ audit_log_task_context(ab, NULL);
}
EXPORT_SYMBOL(audit_log_task_info);
if (!audit_enabled)
return;
+ audit_stamp_context(audit_context());
ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_LOGIN);
if (!ab)
return;
tty = audit_get_tty();
audit_log_format(ab, "pid=%d uid=%u", task_tgid_nr(current), uid);
- audit_log_task_context(ab);
+ audit_log_task_context(ab, NULL);
audit_log_format(ab, " old-auid=%u auid=%u tty=%s old-ses=%u ses=%u res=%d",
oldloginuid, loginuid, tty ? tty_name(tty) : "(none)",
oldsessionid, sessionid, !rc);
audit_put_tty(tty);
+ audit_log_lsm(NULL, true);
audit_log_end(ab);
}