]> 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 48f844b833caf265ce076a6ffbd138f5a389056f..f8c4064db82892e7fd240e3a201543a59996e13a 100644 (file)
@@ -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,9 +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;
-       struct lsmcontext       scaff; /* scaffolding */
 
        err = audit_netlink_ok(skb, msg_type);
        if (err)
@@ -1374,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:
@@ -1440,33 +1457,34 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
                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;
@@ -1573,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= */
@@ -1873,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);
 
@@ -2130,36 +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;
-       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)
 {
@@ -2228,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);
 
@@ -2286,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;
@@ -2296,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);
 }