Commit | Line | Data |
---|---|---|
b886d83c | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
3323eec9 MZ |
2 | /* |
3 | * Copyright (C) 2005,2006,2007,2008 IBM Corporation | |
4 | * | |
5 | * Authors: | |
6 | * Reiner Sailer <sailer@watson.ibm.com> | |
7 | * Mimi Zohar <zohar@us.ibm.com> | |
8 | * | |
3323eec9 MZ |
9 | * File: ima.h |
10 | * internal Integrity Measurement Architecture (IMA) definitions | |
11 | */ | |
12 | ||
13 | #ifndef __LINUX_IMA_H | |
14 | #define __LINUX_IMA_H | |
15 | ||
16 | #include <linux/types.h> | |
17 | #include <linux/crypto.h> | |
cf222217 | 18 | #include <linux/fs.h> |
3323eec9 MZ |
19 | #include <linux/security.h> |
20 | #include <linux/hash.h> | |
21 | #include <linux/tpm.h> | |
22 | #include <linux/audit.h> | |
1525b06d | 23 | #include <crypto/hash_info.h> |
3323eec9 | 24 | |
f381c272 MZ |
25 | #include "../integrity.h" |
26 | ||
94c3aac5 MZ |
27 | #ifdef CONFIG_HAVE_IMA_KEXEC |
28 | #include <asm/ima.h> | |
29 | #endif | |
30 | ||
3e8e5503 | 31 | enum ima_show_type { IMA_SHOW_BINARY, IMA_SHOW_BINARY_NO_FIELD_LEN, |
c019e307 | 32 | IMA_SHOW_BINARY_OLD_STRING_FMT, IMA_SHOW_ASCII }; |
3323eec9 MZ |
33 | enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = 8 }; |
34 | ||
35 | /* digest size for IMA, fits SHA1 or MD5 */ | |
f381c272 | 36 | #define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE |
3323eec9 MZ |
37 | #define IMA_EVENT_NAME_LEN_MAX 255 |
38 | ||
39 | #define IMA_HASH_BITS 9 | |
40 | #define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) | |
41 | ||
adf53a77 RS |
42 | #define IMA_TEMPLATE_FIELD_ID_MAX_LEN 16 |
43 | #define IMA_TEMPLATE_NUM_FIELDS_MAX 15 | |
44 | ||
3ce1217d RS |
45 | #define IMA_TEMPLATE_IMA_NAME "ima" |
46 | #define IMA_TEMPLATE_IMA_FMT "d|n" | |
47 | ||
a756024e RS |
48 | /* current content of the policy */ |
49 | extern int ima_policy_flag; | |
50 | ||
3323eec9 | 51 | /* set during initialization */ |
c7c8bb23 | 52 | extern int ima_hash_algo; |
2fe5d6de | 53 | extern int ima_appraise; |
5c2a640a | 54 | extern struct tpm_chip *ima_tpm_chip; |
3323eec9 | 55 | |
23b57419 RS |
56 | /* IMA event related data */ |
57 | struct ima_event_data { | |
58 | struct integrity_iint_cache *iint; | |
59 | struct file *file; | |
60 | const unsigned char *filename; | |
61 | struct evm_ima_xattr_data *xattr_value; | |
62 | int xattr_len; | |
3878d505 | 63 | const struct modsig *modsig; |
8d94eb9b | 64 | const char *violation; |
86b4da8c PS |
65 | const void *buf; |
66 | int buf_len; | |
23b57419 RS |
67 | }; |
68 | ||
adf53a77 RS |
69 | /* IMA template field data definition */ |
70 | struct ima_field_data { | |
71 | u8 *data; | |
72 | u32 len; | |
73 | }; | |
74 | ||
75 | /* IMA template field definition */ | |
76 | struct ima_template_field { | |
77 | const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN]; | |
23b57419 RS |
78 | int (*field_init)(struct ima_event_data *event_data, |
79 | struct ima_field_data *field_data); | |
80 | void (*field_show)(struct seq_file *m, enum ima_show_type show, | |
81 | struct ima_field_data *field_data); | |
adf53a77 RS |
82 | }; |
83 | ||
84 | /* IMA template descriptor definition */ | |
85 | struct ima_template_desc { | |
3f23d624 | 86 | struct list_head list; |
adf53a77 RS |
87 | char *name; |
88 | char *fmt; | |
89 | int num_fields; | |
b2724d58 | 90 | const struct ima_template_field **fields; |
adf53a77 RS |
91 | }; |
92 | ||
3323eec9 | 93 | struct ima_template_entry { |
14b1da85 | 94 | int pcr; |
140d8022 | 95 | u8 digest[TPM_DIGEST_SIZE]; /* sha1 or md5 measurement hash */ |
a71dc65d RS |
96 | struct ima_template_desc *template_desc; /* template descriptor */ |
97 | u32 template_data_len; | |
98 | struct ima_field_data template_data[0]; /* template related data */ | |
3323eec9 MZ |
99 | }; |
100 | ||
101 | struct ima_queue_entry { | |
102 | struct hlist_node hnext; /* place in hash collision list */ | |
103 | struct list_head later; /* place in ima_measurements list */ | |
104 | struct ima_template_entry *entry; | |
105 | }; | |
106 | extern struct list_head ima_measurements; /* list of all measurements */ | |
107 | ||
94c3aac5 MZ |
108 | /* Some details preceding the binary serialized measurement list */ |
109 | struct ima_kexec_hdr { | |
110 | u16 version; | |
111 | u16 _reserved0; | |
112 | u32 _reserved1; | |
113 | u64 buffer_size; | |
114 | u64 count; | |
115 | }; | |
116 | ||
29d3c1c8 MG |
117 | extern const int read_idmap[]; |
118 | ||
94c3aac5 MZ |
119 | #ifdef CONFIG_HAVE_IMA_KEXEC |
120 | void ima_load_kexec_buffer(void); | |
121 | #else | |
122 | static inline void ima_load_kexec_buffer(void) {} | |
123 | #endif /* CONFIG_HAVE_IMA_KEXEC */ | |
124 | ||
d68a6fe9 MZ |
125 | /* |
126 | * The default binary_runtime_measurements list format is defined as the | |
127 | * platform native format. The canonical format is defined as little-endian. | |
128 | */ | |
129 | extern bool ima_canonical_fmt; | |
130 | ||
3323eec9 | 131 | /* Internal IMA function definitions */ |
3323eec9 | 132 | int ima_init(void); |
bab73937 | 133 | int ima_fs_init(void); |
3323eec9 | 134 | int ima_add_template_entry(struct ima_template_entry *entry, int violation, |
9803d413 RS |
135 | const char *op, struct inode *inode, |
136 | const unsigned char *filename); | |
c7c8bb23 | 137 | int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash); |
11d7646d DK |
138 | int ima_calc_buffer_hash(const void *buf, loff_t len, |
139 | struct ima_digest_data *hash); | |
b6f8f16f RS |
140 | int ima_calc_field_array_hash(struct ima_field_data *field_data, |
141 | struct ima_template_desc *desc, int num_fields, | |
a71dc65d | 142 | struct ima_digest_data *hash); |
09ef5435 | 143 | int __init ima_calc_boot_aggregate(struct ima_digest_data *hash); |
7d802a22 | 144 | void ima_add_violation(struct file *file, const unsigned char *filename, |
8d94eb9b | 145 | struct integrity_iint_cache *iint, |
3323eec9 | 146 | const char *op, const char *cause); |
76bb28f6 | 147 | int ima_init_crypto(void); |
3ce1217d | 148 | void ima_putc(struct seq_file *m, void *data, int datalen); |
45b26133 | 149 | void ima_print_digest(struct seq_file *m, u8 *digest, u32 size); |
19453ce0 MG |
150 | int template_desc_init_fields(const char *template_fmt, |
151 | const struct ima_template_field ***fields, | |
152 | int *num_fields); | |
a71dc65d | 153 | struct ima_template_desc *ima_template_desc_current(void); |
19453ce0 | 154 | struct ima_template_desc *lookup_template_desc(const char *name); |
e5092255 | 155 | bool ima_template_has_modsig(const struct ima_template_desc *ima_template); |
94c3aac5 MZ |
156 | int ima_restore_measurement_entry(struct ima_template_entry *entry); |
157 | int ima_restore_measurement_list(loff_t bufsize, void *buf); | |
7b8589cc | 158 | int ima_measurements_show(struct seq_file *m, void *v); |
d158847a | 159 | unsigned long ima_get_binary_runtime_size(void); |
a71dc65d | 160 | int ima_init_template(void); |
3f23d624 | 161 | void ima_init_template_list(void); |
0b6cf6b9 | 162 | int __init ima_init_digests(void); |
b1694245 JK |
163 | int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event, |
164 | void *lsm_data); | |
3323eec9 MZ |
165 | |
166 | /* | |
167 | * used to protect h_table and sha_table | |
168 | */ | |
169 | extern spinlock_t ima_queue_lock; | |
170 | ||
171 | struct ima_h_table { | |
172 | atomic_long_t len; /* number of stored measurements in the list */ | |
173 | atomic_long_t violations; | |
174 | struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE]; | |
175 | }; | |
176 | extern struct ima_h_table ima_htable; | |
177 | ||
178 | static inline unsigned long ima_hash_key(u8 *digest) | |
179 | { | |
180 | return hash_long(*digest, IMA_HASH_BITS); | |
181 | } | |
182 | ||
2663218b TJB |
183 | #define __ima_hooks(hook) \ |
184 | hook(NONE) \ | |
185 | hook(FILE_CHECK) \ | |
186 | hook(MMAP_CHECK) \ | |
187 | hook(BPRM_CHECK) \ | |
d906c10d | 188 | hook(CREDS_CHECK) \ |
2663218b TJB |
189 | hook(POST_SETATTR) \ |
190 | hook(MODULE_CHECK) \ | |
191 | hook(FIRMWARE_CHECK) \ | |
192 | hook(KEXEC_KERNEL_CHECK) \ | |
193 | hook(KEXEC_INITRAMFS_CHECK) \ | |
194 | hook(POLICY_CHECK) \ | |
b0935123 | 195 | hook(KEXEC_CMDLINE) \ |
2663218b TJB |
196 | hook(MAX_CHECK) |
197 | #define __ima_hook_enumify(ENUM) ENUM, | |
198 | ||
4ad87a3d | 199 | enum ima_hooks { |
2663218b | 200 | __ima_hooks(__ima_hook_enumify) |
4ad87a3d MZ |
201 | }; |
202 | ||
39b07096 TJB |
203 | extern const char *const func_tokens[]; |
204 | ||
205 | struct modsig; | |
206 | ||
3323eec9 | 207 | /* LIM API function definitions */ |
d906c10d | 208 | int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid, |
19453ce0 MG |
209 | int mask, enum ima_hooks func, int *pcr, |
210 | struct ima_template_desc **template_desc); | |
4ad87a3d | 211 | int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func); |
f381c272 | 212 | int ima_collect_measurement(struct integrity_iint_cache *iint, |
cf222217 | 213 | struct file *file, void *buf, loff_t size, |
15588227 | 214 | enum hash_algo algo, struct modsig *modsig); |
f381c272 | 215 | void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, |
bcbc9b0c MZ |
216 | const unsigned char *filename, |
217 | struct evm_ima_xattr_data *xattr_value, | |
3878d505 | 218 | int xattr_len, const struct modsig *modsig, int pcr, |
19453ce0 | 219 | struct ima_template_desc *template_desc); |
e14555e3 NJ |
220 | void process_buffer_measurement(const void *buf, int size, |
221 | const char *eventname, enum ima_hooks func, | |
222 | int pcr); | |
e7c568e0 PM |
223 | void ima_audit_measurement(struct integrity_iint_cache *iint, |
224 | const unsigned char *filename); | |
23b57419 | 225 | int ima_alloc_init_template(struct ima_event_data *event_data, |
19453ce0 MG |
226 | struct ima_template_entry **entry, |
227 | struct ima_template_desc *template_desc); | |
3323eec9 | 228 | int ima_store_template(struct ima_template_entry *entry, int violation, |
14b1da85 ER |
229 | struct inode *inode, |
230 | const unsigned char *filename, int pcr); | |
a7ed7c60 | 231 | void ima_free_template_entry(struct ima_template_entry *entry); |
bc15ed66 | 232 | const char *ima_d_path(const struct path *path, char **pathbuf, char *filename); |
3323eec9 | 233 | |
3323eec9 | 234 | /* IMA policy related functions */ |
d906c10d | 235 | int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, |
19453ce0 MG |
236 | enum ima_hooks func, int mask, int flags, int *pcr, |
237 | struct ima_template_desc **template_desc); | |
3323eec9 MZ |
238 | void ima_init_policy(void); |
239 | void ima_update_policy(void); | |
a756024e | 240 | void ima_update_policy_flag(void); |
6ccd0456 | 241 | ssize_t ima_parse_add_rule(char *); |
4af4662f | 242 | void ima_delete_rules(void); |
0112721d | 243 | int ima_check_policy(void); |
80eae209 PM |
244 | void *ima_policy_start(struct seq_file *m, loff_t *pos); |
245 | void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos); | |
246 | void ima_policy_stop(struct seq_file *m, void *v); | |
247 | int ima_policy_show(struct seq_file *m, void *v); | |
4af4662f | 248 | |
2fe5d6de MZ |
249 | /* Appraise integrity measurements */ |
250 | #define IMA_APPRAISE_ENFORCE 0x01 | |
251 | #define IMA_APPRAISE_FIX 0x02 | |
2faa6ef3 DK |
252 | #define IMA_APPRAISE_LOG 0x04 |
253 | #define IMA_APPRAISE_MODULES 0x08 | |
254 | #define IMA_APPRAISE_FIRMWARE 0x10 | |
19f8a847 | 255 | #define IMA_APPRAISE_POLICY 0x20 |
16c267aa | 256 | #define IMA_APPRAISE_KEXEC 0x40 |
2fe5d6de MZ |
257 | |
258 | #ifdef CONFIG_IMA_APPRAISE | |
4ad87a3d MZ |
259 | int ima_appraise_measurement(enum ima_hooks func, |
260 | struct integrity_iint_cache *iint, | |
d3634d0f DK |
261 | struct file *file, const unsigned char *filename, |
262 | struct evm_ima_xattr_data *xattr_value, | |
39b07096 | 263 | int xattr_len, const struct modsig *modsig); |
d26e1936 | 264 | int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); |
2fe5d6de | 265 | void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); |
d79d72e0 | 266 | enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, |
4ad87a3d | 267 | enum ima_hooks func); |
1525b06d DK |
268 | enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, |
269 | int xattr_len); | |
d3634d0f DK |
270 | int ima_read_xattr(struct dentry *dentry, |
271 | struct evm_ima_xattr_data **xattr_value); | |
2fe5d6de MZ |
272 | |
273 | #else | |
4ad87a3d | 274 | static inline int ima_appraise_measurement(enum ima_hooks func, |
d79d72e0 | 275 | struct integrity_iint_cache *iint, |
2fe5d6de | 276 | struct file *file, |
d3634d0f DK |
277 | const unsigned char *filename, |
278 | struct evm_ima_xattr_data *xattr_value, | |
39b07096 TJB |
279 | int xattr_len, |
280 | const struct modsig *modsig) | |
2fe5d6de MZ |
281 | { |
282 | return INTEGRITY_UNKNOWN; | |
283 | } | |
284 | ||
d26e1936 DK |
285 | static inline int ima_must_appraise(struct inode *inode, int mask, |
286 | enum ima_hooks func) | |
2fe5d6de MZ |
287 | { |
288 | return 0; | |
289 | } | |
290 | ||
291 | static inline void ima_update_xattr(struct integrity_iint_cache *iint, | |
292 | struct file *file) | |
293 | { | |
294 | } | |
d79d72e0 MZ |
295 | |
296 | static inline enum integrity_status ima_get_cache_status(struct integrity_iint_cache | |
4ad87a3d MZ |
297 | *iint, |
298 | enum ima_hooks func) | |
d79d72e0 MZ |
299 | { |
300 | return INTEGRITY_UNKNOWN; | |
301 | } | |
d3634d0f | 302 | |
1525b06d DK |
303 | static inline enum hash_algo |
304 | ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len) | |
d3634d0f | 305 | { |
1525b06d | 306 | return ima_hash_algo; |
d3634d0f DK |
307 | } |
308 | ||
309 | static inline int ima_read_xattr(struct dentry *dentry, | |
310 | struct evm_ima_xattr_data **xattr_value) | |
311 | { | |
312 | return 0; | |
313 | } | |
314 | ||
bb543e39 | 315 | #endif /* CONFIG_IMA_APPRAISE */ |
2fe5d6de | 316 | |
9044d627 TJB |
317 | #ifdef CONFIG_IMA_APPRAISE_MODSIG |
318 | bool ima_hook_supports_modsig(enum ima_hooks func); | |
39b07096 TJB |
319 | int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, |
320 | struct modsig **modsig); | |
15588227 | 321 | void ima_collect_modsig(struct modsig *modsig, const void *buf, loff_t size); |
3878d505 TJB |
322 | int ima_get_modsig_digest(const struct modsig *modsig, enum hash_algo *algo, |
323 | const u8 **digest, u32 *digest_size); | |
324 | int ima_get_raw_modsig(const struct modsig *modsig, const void **data, | |
325 | u32 *data_len); | |
39b07096 | 326 | void ima_free_modsig(struct modsig *modsig); |
9044d627 TJB |
327 | #else |
328 | static inline bool ima_hook_supports_modsig(enum ima_hooks func) | |
329 | { | |
330 | return false; | |
331 | } | |
39b07096 TJB |
332 | |
333 | static inline int ima_read_modsig(enum ima_hooks func, const void *buf, | |
334 | loff_t buf_len, struct modsig **modsig) | |
335 | { | |
336 | return -EOPNOTSUPP; | |
337 | } | |
338 | ||
15588227 TJB |
339 | static inline void ima_collect_modsig(struct modsig *modsig, const void *buf, |
340 | loff_t size) | |
341 | { | |
342 | } | |
343 | ||
3878d505 TJB |
344 | static inline int ima_get_modsig_digest(const struct modsig *modsig, |
345 | enum hash_algo *algo, const u8 **digest, | |
346 | u32 *digest_size) | |
347 | { | |
348 | return -EOPNOTSUPP; | |
349 | } | |
350 | ||
351 | static inline int ima_get_raw_modsig(const struct modsig *modsig, | |
352 | const void **data, u32 *data_len) | |
353 | { | |
354 | return -EOPNOTSUPP; | |
355 | } | |
356 | ||
39b07096 TJB |
357 | static inline void ima_free_modsig(struct modsig *modsig) |
358 | { | |
359 | } | |
9044d627 TJB |
360 | #endif /* CONFIG_IMA_APPRAISE_MODSIG */ |
361 | ||
4af4662f MZ |
362 | /* LSM based policy rules require audit */ |
363 | #ifdef CONFIG_IMA_LSM_RULES | |
364 | ||
365 | #define security_filter_rule_init security_audit_rule_init | |
366 | #define security_filter_rule_match security_audit_rule_match | |
367 | ||
368 | #else | |
369 | ||
370 | static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr, | |
371 | void **lsmrule) | |
372 | { | |
373 | return -EINVAL; | |
374 | } | |
375 | ||
376 | static inline int security_filter_rule_match(u32 secid, u32 field, u32 op, | |
90462a5b | 377 | void *lsmrule) |
4af4662f MZ |
378 | { |
379 | return -EINVAL; | |
380 | } | |
5d659f28 | 381 | #endif /* CONFIG_IMA_LSM_RULES */ |
80eae209 PM |
382 | |
383 | #ifdef CONFIG_IMA_READ_POLICY | |
384 | #define POLICY_FILE_FLAGS (S_IWUSR | S_IRUSR) | |
385 | #else | |
386 | #define POLICY_FILE_FLAGS S_IWUSR | |
5d659f28 | 387 | #endif /* CONFIG_IMA_READ_POLICY */ |
80eae209 PM |
388 | |
389 | #endif /* __LINUX_IMA_H */ |