diff options
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 97 |
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 |