]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blobdiff - kernel/auditsc.c
UBUNTU: Ubuntu-5.11.0-20.21
[mirror_ubuntu-hirsute-kernel.git] / kernel / auditsc.c
index ce8c9e2279ba93fddc2387d327646161c5787a8a..1a3ae420f831918145df913eba3d148e69101489 100644 (file)
@@ -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;
 };
@@ -471,7 +471,7 @@ static int audit_filter_rules(struct task_struct *tsk,
 {
        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);
@@ -665,14 +665,15 @@ static int audit_filter_rules(struct task_struct *tsk,
                           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:
@@ -682,21 +683,21 @@ static int audit_filter_rules(struct task_struct *tsk,
                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;
                                                }
@@ -705,9 +706,9 @@ static int audit_filter_rules(struct task_struct *tsk,
                                /* 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;
@@ -951,10 +952,12 @@ int audit_alloc(struct task_struct *tsk)
                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);
@@ -982,12 +985,11 @@ 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;
 
        ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID);
@@ -997,15 +999,7 @@ 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) {
-               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);
@@ -1232,23 +1226,14 @@ static void show_special(struct audit_context *context, int *call_panic)
                                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,
@@ -1391,20 +1376,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
                                 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) {
@@ -1470,6 +1443,52 @@ out:
        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;
@@ -1565,7 +1584,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;
        }
@@ -1574,7 +1593,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) {
@@ -1593,6 +1612,7 @@ static void audit_log_exit(void)
        }
 
        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);
@@ -1752,7 +1772,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;
@@ -1955,7 +1975,7 @@ static void audit_copy_inode(struct audit_names *name,
        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;
@@ -2186,6 +2206,21 @@ void __audit_inode_child(struct inode *parent,
 }
 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
@@ -2197,6 +2232,12 @@ EXPORT_SYMBOL_GPL(__audit_inode_child);
 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)
@@ -2305,7 +2346,7 @@ void __audit_ipc_obj(struct kern_ipc_perm *ipcp)
        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;
 }
 
@@ -2400,7 +2441,7 @@ void __audit_ptrace(struct task_struct *t)
        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);
 }
 
@@ -2427,7 +2468,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(t, &ctx->target_sid);
+               security_task_getsecid(t, &ctx->target_lsm);
                memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN);
                return 0;
        }
@@ -2448,7 +2489,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(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++;
 
@@ -2586,7 +2627,7 @@ void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
                         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);
@@ -2609,7 +2650,7 @@ static void audit_log_task(struct audit_buffer *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);
@@ -2632,11 +2673,13 @@ void audit_core_dumps(long signr)
        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);
 }