Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/security/ipe/audit.c
49062 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* Copyright (C) 2020-2024 Microsoft Corporation. All rights reserved.
4
*/
5
6
#include <linux/slab.h>
7
#include <linux/audit.h>
8
#include <linux/types.h>
9
#include <crypto/sha2.h>
10
11
#include "ipe.h"
12
#include "eval.h"
13
#include "hooks.h"
14
#include "policy.h"
15
#include "audit.h"
16
#include "digest.h"
17
18
#define ACTSTR(x) ((x) == IPE_ACTION_ALLOW ? "ALLOW" : "DENY")
19
20
#define IPE_AUDIT_HASH_ALG "sha256" /* keep in sync with audit_policy() */
21
22
#define AUDIT_POLICY_LOAD_FMT "policy_name=\"%s\" policy_version=%hu.%hu.%hu "\
23
"policy_digest=" IPE_AUDIT_HASH_ALG ":"
24
#define AUDIT_POLICY_LOAD_NULL_FMT "policy_name=? policy_version=? "\
25
"policy_digest=?"
26
#define AUDIT_OLD_ACTIVE_POLICY_FMT "old_active_pol_name=\"%s\" "\
27
"old_active_pol_version=%hu.%hu.%hu "\
28
"old_policy_digest=" IPE_AUDIT_HASH_ALG ":"
29
#define AUDIT_OLD_ACTIVE_POLICY_NULL_FMT "old_active_pol_name=? "\
30
"old_active_pol_version=? "\
31
"old_policy_digest=?"
32
#define AUDIT_NEW_ACTIVE_POLICY_FMT "new_active_pol_name=\"%s\" "\
33
"new_active_pol_version=%hu.%hu.%hu "\
34
"new_policy_digest=" IPE_AUDIT_HASH_ALG ":"
35
36
static const char *const audit_op_names[__IPE_OP_MAX + 1] = {
37
"EXECUTE",
38
"FIRMWARE",
39
"KMODULE",
40
"KEXEC_IMAGE",
41
"KEXEC_INITRAMFS",
42
"POLICY",
43
"X509_CERT",
44
"UNKNOWN",
45
};
46
47
static const char *const audit_hook_names[__IPE_HOOK_MAX] = {
48
"BPRM_CHECK",
49
"BPRM_CREDS_FOR_EXEC",
50
"MMAP",
51
"MPROTECT",
52
"KERNEL_READ",
53
"KERNEL_LOAD",
54
};
55
56
static const char *const audit_prop_names[__IPE_PROP_MAX] = {
57
"boot_verified=FALSE",
58
"boot_verified=TRUE",
59
"dmverity_roothash=",
60
"dmverity_signature=FALSE",
61
"dmverity_signature=TRUE",
62
"fsverity_digest=",
63
"fsverity_signature=FALSE",
64
"fsverity_signature=TRUE",
65
};
66
67
/**
68
* audit_dmv_roothash() - audit the roothash of a dmverity_roothash property.
69
* @ab: Supplies a pointer to the audit_buffer to append to.
70
* @rh: Supplies a pointer to the digest structure.
71
*/
72
static void audit_dmv_roothash(struct audit_buffer *ab, const void *rh)
73
{
74
audit_log_format(ab, "%s", audit_prop_names[IPE_PROP_DMV_ROOTHASH]);
75
ipe_digest_audit(ab, rh);
76
}
77
78
/**
79
* audit_fsv_digest() - audit the digest of a fsverity_digest property.
80
* @ab: Supplies a pointer to the audit_buffer to append to.
81
* @d: Supplies a pointer to the digest structure.
82
*/
83
static void audit_fsv_digest(struct audit_buffer *ab, const void *d)
84
{
85
audit_log_format(ab, "%s", audit_prop_names[IPE_PROP_FSV_DIGEST]);
86
ipe_digest_audit(ab, d);
87
}
88
89
/**
90
* audit_rule() - audit an IPE policy rule.
91
* @ab: Supplies a pointer to the audit_buffer to append to.
92
* @r: Supplies a pointer to the ipe_rule to approximate a string form for.
93
*/
94
static void audit_rule(struct audit_buffer *ab, const struct ipe_rule *r)
95
{
96
const struct ipe_prop *ptr;
97
98
audit_log_format(ab, " rule=\"op=%s ", audit_op_names[r->op]);
99
100
list_for_each_entry(ptr, &r->props, next) {
101
switch (ptr->type) {
102
case IPE_PROP_DMV_ROOTHASH:
103
audit_dmv_roothash(ab, ptr->value);
104
break;
105
case IPE_PROP_FSV_DIGEST:
106
audit_fsv_digest(ab, ptr->value);
107
break;
108
default:
109
audit_log_format(ab, "%s", audit_prop_names[ptr->type]);
110
break;
111
}
112
113
audit_log_format(ab, " ");
114
}
115
116
audit_log_format(ab, "action=%s\"", ACTSTR(r->action));
117
}
118
119
/**
120
* ipe_audit_match() - Audit a rule match in a policy evaluation.
121
* @ctx: Supplies a pointer to the evaluation context that was used in the
122
* evaluation.
123
* @match_type: Supplies the scope of the match: rule, operation default,
124
* global default.
125
* @act: Supplies the IPE's evaluation decision, deny or allow.
126
* @r: Supplies a pointer to the rule that was matched, if possible.
127
*/
128
void ipe_audit_match(const struct ipe_eval_ctx *const ctx,
129
enum ipe_match match_type,
130
enum ipe_action_type act, const struct ipe_rule *const r)
131
{
132
const char *op = audit_op_names[ctx->op];
133
char comm[sizeof(current->comm)];
134
struct audit_buffer *ab;
135
struct inode *inode;
136
137
if (act != IPE_ACTION_DENY && !READ_ONCE(success_audit))
138
return;
139
140
ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN,
141
AUDIT_IPE_ACCESS);
142
if (!ab)
143
return;
144
145
audit_log_format(ab, "ipe_op=%s ipe_hook=%s enforcing=%d pid=%d comm=",
146
op, audit_hook_names[ctx->hook], READ_ONCE(enforce),
147
task_tgid_nr(current));
148
audit_log_untrustedstring(ab, get_task_comm(comm, current));
149
150
if (ctx->file) {
151
audit_log_d_path(ab, " path=", &ctx->file->f_path);
152
inode = file_inode(ctx->file);
153
if (inode) {
154
audit_log_format(ab, " dev=");
155
audit_log_untrustedstring(ab, inode->i_sb->s_id);
156
audit_log_format(ab, " ino=%lu", inode->i_ino);
157
} else {
158
audit_log_format(ab, " dev=? ino=?");
159
}
160
} else {
161
audit_log_format(ab, " path=? dev=? ino=?");
162
}
163
164
if (match_type == IPE_MATCH_RULE)
165
audit_rule(ab, r);
166
else if (match_type == IPE_MATCH_TABLE)
167
audit_log_format(ab, " rule=\"DEFAULT op=%s action=%s\"", op,
168
ACTSTR(act));
169
else
170
audit_log_format(ab, " rule=\"DEFAULT action=%s\"",
171
ACTSTR(act));
172
173
audit_log_end(ab);
174
}
175
176
/**
177
* audit_policy() - Audit a policy's name, version and thumbprint to @ab.
178
* @ab: Supplies a pointer to the audit buffer to append to.
179
* @audit_format: Supplies a pointer to the audit format string
180
* @p: Supplies a pointer to the policy to audit.
181
*/
182
static void audit_policy(struct audit_buffer *ab,
183
const char *audit_format,
184
const struct ipe_policy *const p)
185
{
186
u8 digest[SHA256_DIGEST_SIZE];
187
188
sha256(p->pkcs7, p->pkcs7len, digest);
189
190
audit_log_format(ab, audit_format, p->parsed->name,
191
p->parsed->version.major, p->parsed->version.minor,
192
p->parsed->version.rev);
193
audit_log_n_hex(ab, digest, sizeof(digest));
194
}
195
196
/**
197
* ipe_audit_policy_activation() - Audit a policy being activated.
198
* @op: Supplies a pointer to the previously activated policy to audit.
199
* @np: Supplies a pointer to the newly activated policy to audit.
200
*/
201
void ipe_audit_policy_activation(const struct ipe_policy *const op,
202
const struct ipe_policy *const np)
203
{
204
struct audit_buffer *ab;
205
206
ab = audit_log_start(audit_context(), GFP_KERNEL,
207
AUDIT_IPE_CONFIG_CHANGE);
208
if (!ab)
209
return;
210
211
if (op) {
212
audit_policy(ab, AUDIT_OLD_ACTIVE_POLICY_FMT, op);
213
audit_log_format(ab, " ");
214
} else {
215
/*
216
* old active policy can be NULL if there is no kernel
217
* built-in policy
218
*/
219
audit_log_format(ab, AUDIT_OLD_ACTIVE_POLICY_NULL_FMT);
220
audit_log_format(ab, " ");
221
}
222
audit_policy(ab, AUDIT_NEW_ACTIVE_POLICY_FMT, np);
223
audit_log_format(ab, " auid=%u ses=%u lsm=ipe res=1",
224
from_kuid(&init_user_ns, audit_get_loginuid(current)),
225
audit_get_sessionid(current));
226
227
audit_log_end(ab);
228
}
229
230
/**
231
* ipe_audit_policy_load() - Audit a policy loading event.
232
* @p: Supplies a pointer to the policy to audit or an error pointer.
233
*/
234
void ipe_audit_policy_load(const struct ipe_policy *const p)
235
{
236
struct audit_buffer *ab;
237
int err = 0;
238
239
ab = audit_log_start(audit_context(), GFP_KERNEL,
240
AUDIT_IPE_POLICY_LOAD);
241
if (!ab)
242
return;
243
244
if (!IS_ERR(p)) {
245
audit_policy(ab, AUDIT_POLICY_LOAD_FMT, p);
246
} else {
247
audit_log_format(ab, AUDIT_POLICY_LOAD_NULL_FMT);
248
err = PTR_ERR(p);
249
}
250
251
audit_log_format(ab, " auid=%u ses=%u lsm=ipe res=%d errno=%d",
252
from_kuid(&init_user_ns, audit_get_loginuid(current)),
253
audit_get_sessionid(current), !err, err);
254
255
audit_log_end(ab);
256
}
257
258
/**
259
* ipe_audit_enforce() - Audit a change in IPE's enforcement state.
260
* @new_enforce: The new value enforce to be set.
261
* @old_enforce: The old value currently in enforce.
262
*/
263
void ipe_audit_enforce(bool new_enforce, bool old_enforce)
264
{
265
struct audit_buffer *ab;
266
267
ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS);
268
if (!ab)
269
return;
270
271
audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS,
272
"enforcing=%d old_enforcing=%d auid=%u ses=%u"
273
" enabled=1 old-enabled=1 lsm=ipe res=1",
274
new_enforce, old_enforce,
275
from_kuid(&init_user_ns, audit_get_loginuid(current)),
276
audit_get_sessionid(current));
277
278
audit_log_end(ab);
279
}
280
281