]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - kernel/audit.c
UBUNTU: SAUCE: drm/i915: Tweaked Wa_14010685332 for all PCHs
[mirror_ubuntu-hirsute-kernel.git] / kernel / audit.c
index 1ffc2e059027d99477053b25cdc10598c7d5385a..f8c4064db82892e7fd240e3a201543a59996e13a 100644 (file)
@@ -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]
@@ -394,10 +394,11 @@ static int audit_log_config_change(char *function_name, u32 new, u32 old,
                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;
 }
@@ -1069,13 +1070,31 @@ static void audit_log_common_recv_msg(struct audit_context *context,
                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)
@@ -1190,8 +1209,6 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
        struct audit_buffer     *ab;
        u16                     msg_type = nlh->nlmsg_type;
        struct audit_sig_info   *sig_data;
-       char                    *ctx = NULL;
-       u32                     len;
 
        err = audit_netlink_ok(skb, msg_type);
        if (err)
@@ -1373,6 +1390,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                                audit_log_n_untrustedstring(ab, str, data_len);
                        }
                        audit_log_end(ab);
+                       audit_log_lsm(NULL, false);
                }
                break;
        case AUDIT_ADD_RULE:
@@ -1439,29 +1457,34 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                kfree(new);
                break;
        }
-       case AUDIT_SIGNAL_INFO:
-               len = 0;
-               if (audit_sig_sid) {
-                       err = security_secid_to_secctx(audit_sig_sid, &ctx, &len);
+       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,
+                                                      &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 (audit_sig_sid)
-                               security_release_secctx(ctx, len);
+                       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 (audit_sig_sid) {
-                       memcpy(sig_data->ctx, ctx, len);
-                       security_release_secctx(ctx, len);
+               if (lsmblob_is_set(&audit_sig_lsm)) {
+                       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;
@@ -1568,7 +1591,7 @@ static void audit_log_multicast(int group, const char *op, int err)
                         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= */
@@ -1868,6 +1891,11 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask,
        /* 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);
 
@@ -2125,34 +2153,103 @@ void audit_log_key(struct audit_buffer *ab, char *key)
                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;
-       u32 sid;
+       struct lsmblob localblob;
+       struct lsmcontext lsmdata;
 
-       security_task_getsecid(current, &sid);
-       if (!sid)
+       /*
+        * 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(sid, &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);
-       security_release_secctx(ctx, len);
-       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)
 {
@@ -2221,7 +2318,7 @@ void audit_log_task_info(struct audit_buffer *ab)
        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);
 
@@ -2279,6 +2376,7 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid,
        if (!audit_enabled)
                return;
 
+       audit_stamp_context(audit_context());
        ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_LOGIN);
        if (!ab)
                return;
@@ -2289,11 +2387,12 @@ static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid,
        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);
 }
 
@@ -2353,7 +2452,7 @@ int audit_signal_info(int sig, struct task_struct *t)
                        audit_sig_uid = auid;
                else
                        audit_sig_uid = uid;
-               security_task_getsecid(current, &audit_sig_sid);
+               security_task_getsecid(current, &audit_sig_lsm);
        }
 
        return audit_signal_info_syscall(t);