summaryrefslogtreecommitdiffstats
path: root/kernel/auditsc.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r--kernel/auditsc.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 3828ad5fb8f..e9761ad22ce 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -158,6 +158,16 @@ struct audit_aux_data_capset {
struct audit_cap_data cap;
};
+struct audit_aux_data_crypto_op {
+ struct audit_aux_data d;
+ int op;
+ int tfm;
+ int ctx; /* -1 means N/A */
+ int ctx2; /* -1 means N/A */
+ const char *algorithm; /* NULL means N/A */
+ const char *operation; /* NULL means N/A */
+};
+
struct audit_tree_refs {
struct audit_tree_refs *next;
struct audit_chunk *c[31];
@@ -633,6 +643,24 @@ static int audit_filter_rules(struct task_struct *tsk,
case AUDIT_FILETYPE:
result = audit_match_filetype(ctx, f->val);
break;
+ case AUDIT_CRYPTO_OP: {
+ struct audit_aux_data *aux;
+
+ if (!ctx)
+ break;
+ for (aux = ctx->aux; aux; aux = aux->next) {
+ struct audit_aux_data_crypto_op *ax;
+
+ if (aux->type != AUDIT_CRYPTO_USERSPACE_OP)
+ continue;
+ ax = (void *)aux;
+ result = audit_comparator(ax->op, f->op,
+ f->val);
+ if (result)
+ break;
+ }
+ break;
+ }
}
if (!result) {
@@ -1201,6 +1229,37 @@ static void audit_log_cap(struct audit_buffer *ab, char *prefix, kernel_cap_t *c
}
}
+static void log_crypto_op(struct audit_buffer *ab,
+ const struct audit_aux_data_crypto_op *crypto)
+{
+ static const char *const ops[] = {
+ [AUDIT_CRYPTO_OP_TFM_NEW] = "tfm_new",
+ [AUDIT_CRYPTO_OP_TFM_KEY_IMPORT] = "tfm_key_import",
+ [AUDIT_CRYPTO_OP_TFM_DEL] = "tfm_del",
+ [AUDIT_CRYPTO_OP_CTX_NEW] = "ctx_new",
+ [AUDIT_CRYPTO_OP_CTX_OP] = "ctx_op",
+ [AUDIT_CRYPTO_OP_CTX_DEL] = "ctx_del",
+ };
+
+ if (crypto->op < ARRAY_SIZE(ops) && ops[crypto->op] != NULL)
+ audit_log_format(ab, "crypto_op=%s", ops[crypto->op]);
+ else
+ audit_log_format(ab, "crypto_op=%d", crypto->op);
+ audit_log_format(ab, " tfm=%d", crypto->tfm);
+ if (crypto->ctx != -1)
+ audit_log_format(ab, " ctx=%d", crypto->ctx);
+ if (crypto->ctx2 != -1)
+ audit_log_format(ab, " ctx2=%d", crypto->ctx2);
+ if (crypto->algorithm != NULL) {
+ audit_log_format(ab, " algorithm=");
+ audit_log_string(ab, crypto->algorithm);
+ }
+ if (crypto->operation != NULL) {
+ audit_log_format(ab, " operation=");
+ audit_log_string(ab, crypto->operation);
+ }
+}
+
static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
{
kernel_cap_t *perm = &name->fcap.permitted;
@@ -1404,6 +1463,11 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
audit_log_cap(ab, "new_pe", &axs->new_pcap.effective);
break; }
+ case AUDIT_CRYPTO_USERSPACE_OP: {
+ struct audit_aux_data_crypto_op *axc = (void *)aux;
+ log_crypto_op(ab, axc);
+ break; }
+
}
audit_log_end(ab);
}
@@ -2464,6 +2528,39 @@ int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
}
/**
+ * __audit_log_crypto_op - store information about an user-space crypto op
+ * @op: AUDIT_CRYPTO_OP_*
+ * @tfm: unique transform ID
+ * @ctx: unique context ID, or -1
+ * @ctx2: secondary context ID, or -1
+ * @algorithm: algorithm (crypto API transform) name, or NULL
+ * @operation: more detailed operation description, or NULL
+ */
+int __audit_log_crypto_op(int op, int tfm, int ctx, int ctx2,
+ const char *algorithm, const char *operation)
+{
+ struct audit_aux_data_crypto_op *ax;
+ struct audit_context *context = current->audit_context;
+
+ ax = kmalloc(sizeof(*ax), GFP_KERNEL);
+ if (!ax)
+ return -ENOMEM;
+
+ ax->d.type = AUDIT_CRYPTO_USERSPACE_OP;
+ ax->d.next = context->aux;
+ context->aux = (void *)ax;
+
+ ax->op = op;
+ ax->tfm = tfm;
+ ax->ctx = ctx;
+ ax->ctx2 = ctx2;
+ ax->algorithm = algorithm;
+ ax->operation = operation;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(__audit_log_crypto_op);
+
+/**
* __audit_log_capset - store information about the arguments to the capset syscall
* @pid: target pid of the capset call
* @new: the new credentials