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; | |
8d94eb9b | 63 | const char *violation; |
86b4da8c PS |
64 | const void *buf; |
65 | int buf_len; | |
23b57419 RS |
66 | }; |
67 | ||
adf53a77 RS |
68 | /* IMA template field data definition */ |
69 | struct ima_field_data { | |
70 | u8 *data; | |
71 | u32 len; | |
72 | }; | |
73 | ||
74 | /* IMA template field definition */ | |
75 | struct ima_template_field { | |
76 | const char field_id[IMA_TEMPLATE_FIELD_ID_MAX_LEN]; | |
23b57419 RS |
77 | int (*field_init)(struct ima_event_data *event_data, |
78 | struct ima_field_data *field_data); | |
79 | void (*field_show)(struct seq_file *m, enum ima_show_type show, | |
80 | struct ima_field_data *field_data); | |
adf53a77 RS |
81 | }; |
82 | ||
83 | /* IMA template descriptor definition */ | |
84 | struct ima_template_desc { | |
3f23d624 | 85 | struct list_head list; |
adf53a77 RS |
86 | char *name; |
87 | char *fmt; | |
88 | int num_fields; | |
b2724d58 | 89 | const struct ima_template_field **fields; |
adf53a77 RS |
90 | }; |
91 | ||
3323eec9 | 92 | struct ima_template_entry { |
14b1da85 | 93 | int pcr; |
140d8022 | 94 | u8 digest[TPM_DIGEST_SIZE]; /* sha1 or md5 measurement hash */ |
a71dc65d RS |
95 | struct ima_template_desc *template_desc; /* template descriptor */ |
96 | u32 template_data_len; | |
97 | struct ima_field_data template_data[0]; /* template related data */ | |
3323eec9 MZ |
98 | }; |
99 | ||
100 | struct ima_queue_entry { | |
101 | struct hlist_node hnext; /* place in hash collision list */ | |
102 | struct list_head later; /* place in ima_measurements list */ | |
103 | struct ima_template_entry *entry; | |
104 | }; | |
105 | extern struct list_head ima_measurements; /* list of all measurements */ | |
106 | ||
94c3aac5 MZ |
107 | /* Some details preceding the binary serialized measurement list */ |
108 | struct ima_kexec_hdr { | |
109 | u16 version; | |
110 | u16 _reserved0; | |
111 | u32 _reserved1; | |
112 | u64 buffer_size; | |
113 | u64 count; | |
114 | }; | |
115 | ||
116 | #ifdef CONFIG_HAVE_IMA_KEXEC | |
117 | void ima_load_kexec_buffer(void); | |
118 | #else | |
119 | static inline void ima_load_kexec_buffer(void) {} | |
120 | #endif /* CONFIG_HAVE_IMA_KEXEC */ | |
121 | ||
d68a6fe9 MZ |
122 | /* |
123 | * The default binary_runtime_measurements list format is defined as the | |
124 | * platform native format. The canonical format is defined as little-endian. | |
125 | */ | |
126 | extern bool ima_canonical_fmt; | |
127 | ||
3323eec9 | 128 | /* Internal IMA function definitions */ |
3323eec9 | 129 | int ima_init(void); |
bab73937 | 130 | int ima_fs_init(void); |
3323eec9 | 131 | int ima_add_template_entry(struct ima_template_entry *entry, int violation, |
9803d413 RS |
132 | const char *op, struct inode *inode, |
133 | const unsigned char *filename); | |
c7c8bb23 | 134 | int ima_calc_file_hash(struct file *file, struct ima_digest_data *hash); |
11d7646d DK |
135 | int ima_calc_buffer_hash(const void *buf, loff_t len, |
136 | struct ima_digest_data *hash); | |
b6f8f16f RS |
137 | int ima_calc_field_array_hash(struct ima_field_data *field_data, |
138 | struct ima_template_desc *desc, int num_fields, | |
a71dc65d | 139 | struct ima_digest_data *hash); |
09ef5435 | 140 | int __init ima_calc_boot_aggregate(struct ima_digest_data *hash); |
7d802a22 | 141 | void ima_add_violation(struct file *file, const unsigned char *filename, |
8d94eb9b | 142 | struct integrity_iint_cache *iint, |
3323eec9 | 143 | const char *op, const char *cause); |
76bb28f6 | 144 | int ima_init_crypto(void); |
3ce1217d | 145 | void ima_putc(struct seq_file *m, void *data, int datalen); |
45b26133 | 146 | void ima_print_digest(struct seq_file *m, u8 *digest, u32 size); |
19453ce0 MG |
147 | int template_desc_init_fields(const char *template_fmt, |
148 | const struct ima_template_field ***fields, | |
149 | int *num_fields); | |
a71dc65d | 150 | struct ima_template_desc *ima_template_desc_current(void); |
19453ce0 | 151 | struct ima_template_desc *lookup_template_desc(const char *name); |
94c3aac5 MZ |
152 | int ima_restore_measurement_entry(struct ima_template_entry *entry); |
153 | int ima_restore_measurement_list(loff_t bufsize, void *buf); | |
7b8589cc | 154 | int ima_measurements_show(struct seq_file *m, void *v); |
d158847a | 155 | unsigned long ima_get_binary_runtime_size(void); |
a71dc65d | 156 | int ima_init_template(void); |
3f23d624 | 157 | void ima_init_template_list(void); |
0b6cf6b9 | 158 | int __init ima_init_digests(void); |
b1694245 JK |
159 | int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event, |
160 | void *lsm_data); | |
3323eec9 MZ |
161 | |
162 | /* | |
163 | * used to protect h_table and sha_table | |
164 | */ | |
165 | extern spinlock_t ima_queue_lock; | |
166 | ||
167 | struct ima_h_table { | |
168 | atomic_long_t len; /* number of stored measurements in the list */ | |
169 | atomic_long_t violations; | |
170 | struct hlist_head queue[IMA_MEASURE_HTABLE_SIZE]; | |
171 | }; | |
172 | extern struct ima_h_table ima_htable; | |
173 | ||
174 | static inline unsigned long ima_hash_key(u8 *digest) | |
175 | { | |
176 | return hash_long(*digest, IMA_HASH_BITS); | |
177 | } | |
178 | ||
2663218b TJB |
179 | #define __ima_hooks(hook) \ |
180 | hook(NONE) \ | |
181 | hook(FILE_CHECK) \ | |
182 | hook(MMAP_CHECK) \ | |
183 | hook(BPRM_CHECK) \ | |
d906c10d | 184 | hook(CREDS_CHECK) \ |
2663218b TJB |
185 | hook(POST_SETATTR) \ |
186 | hook(MODULE_CHECK) \ | |
187 | hook(FIRMWARE_CHECK) \ | |
188 | hook(KEXEC_KERNEL_CHECK) \ | |
189 | hook(KEXEC_INITRAMFS_CHECK) \ | |
190 | hook(POLICY_CHECK) \ | |
b0935123 | 191 | hook(KEXEC_CMDLINE) \ |
2663218b TJB |
192 | hook(MAX_CHECK) |
193 | #define __ima_hook_enumify(ENUM) ENUM, | |
194 | ||
4ad87a3d | 195 | enum ima_hooks { |
2663218b | 196 | __ima_hooks(__ima_hook_enumify) |
4ad87a3d MZ |
197 | }; |
198 | ||
39b07096 TJB |
199 | extern const char *const func_tokens[]; |
200 | ||
201 | struct modsig; | |
202 | ||
3323eec9 | 203 | /* LIM API function definitions */ |
d906c10d | 204 | int ima_get_action(struct inode *inode, const struct cred *cred, u32 secid, |
19453ce0 MG |
205 | int mask, enum ima_hooks func, int *pcr, |
206 | struct ima_template_desc **template_desc); | |
4ad87a3d | 207 | int ima_must_measure(struct inode *inode, int mask, enum ima_hooks func); |
f381c272 | 208 | int ima_collect_measurement(struct integrity_iint_cache *iint, |
cf222217 MZ |
209 | struct file *file, void *buf, loff_t size, |
210 | enum hash_algo algo); | |
f381c272 | 211 | void ima_store_measurement(struct integrity_iint_cache *iint, struct file *file, |
bcbc9b0c MZ |
212 | const unsigned char *filename, |
213 | struct evm_ima_xattr_data *xattr_value, | |
19453ce0 MG |
214 | int xattr_len, int pcr, |
215 | struct ima_template_desc *template_desc); | |
e7c568e0 PM |
216 | void ima_audit_measurement(struct integrity_iint_cache *iint, |
217 | const unsigned char *filename); | |
23b57419 | 218 | int ima_alloc_init_template(struct ima_event_data *event_data, |
19453ce0 MG |
219 | struct ima_template_entry **entry, |
220 | struct ima_template_desc *template_desc); | |
3323eec9 | 221 | int ima_store_template(struct ima_template_entry *entry, int violation, |
14b1da85 ER |
222 | struct inode *inode, |
223 | const unsigned char *filename, int pcr); | |
a7ed7c60 | 224 | void ima_free_template_entry(struct ima_template_entry *entry); |
bc15ed66 | 225 | const char *ima_d_path(const struct path *path, char **pathbuf, char *filename); |
3323eec9 | 226 | |
3323eec9 | 227 | /* IMA policy related functions */ |
d906c10d | 228 | int ima_match_policy(struct inode *inode, const struct cred *cred, u32 secid, |
19453ce0 MG |
229 | enum ima_hooks func, int mask, int flags, int *pcr, |
230 | struct ima_template_desc **template_desc); | |
3323eec9 MZ |
231 | void ima_init_policy(void); |
232 | void ima_update_policy(void); | |
a756024e | 233 | void ima_update_policy_flag(void); |
6ccd0456 | 234 | ssize_t ima_parse_add_rule(char *); |
4af4662f | 235 | void ima_delete_rules(void); |
0112721d | 236 | int ima_check_policy(void); |
80eae209 PM |
237 | void *ima_policy_start(struct seq_file *m, loff_t *pos); |
238 | void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos); | |
239 | void ima_policy_stop(struct seq_file *m, void *v); | |
240 | int ima_policy_show(struct seq_file *m, void *v); | |
4af4662f | 241 | |
2fe5d6de MZ |
242 | /* Appraise integrity measurements */ |
243 | #define IMA_APPRAISE_ENFORCE 0x01 | |
244 | #define IMA_APPRAISE_FIX 0x02 | |
2faa6ef3 DK |
245 | #define IMA_APPRAISE_LOG 0x04 |
246 | #define IMA_APPRAISE_MODULES 0x08 | |
247 | #define IMA_APPRAISE_FIRMWARE 0x10 | |
19f8a847 | 248 | #define IMA_APPRAISE_POLICY 0x20 |
16c267aa | 249 | #define IMA_APPRAISE_KEXEC 0x40 |
2fe5d6de MZ |
250 | |
251 | #ifdef CONFIG_IMA_APPRAISE | |
4ad87a3d MZ |
252 | int ima_appraise_measurement(enum ima_hooks func, |
253 | struct integrity_iint_cache *iint, | |
d3634d0f DK |
254 | struct file *file, const unsigned char *filename, |
255 | struct evm_ima_xattr_data *xattr_value, | |
39b07096 | 256 | int xattr_len, const struct modsig *modsig); |
d26e1936 | 257 | int ima_must_appraise(struct inode *inode, int mask, enum ima_hooks func); |
2fe5d6de | 258 | void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file); |
d79d72e0 | 259 | enum integrity_status ima_get_cache_status(struct integrity_iint_cache *iint, |
4ad87a3d | 260 | enum ima_hooks func); |
1525b06d DK |
261 | enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, |
262 | int xattr_len); | |
d3634d0f DK |
263 | int ima_read_xattr(struct dentry *dentry, |
264 | struct evm_ima_xattr_data **xattr_value); | |
2fe5d6de MZ |
265 | |
266 | #else | |
4ad87a3d | 267 | static inline int ima_appraise_measurement(enum ima_hooks func, |
d79d72e0 | 268 | struct integrity_iint_cache *iint, |
2fe5d6de | 269 | struct file *file, |
d3634d0f DK |
270 | const unsigned char *filename, |
271 | struct evm_ima_xattr_data *xattr_value, | |
39b07096 TJB |
272 | int xattr_len, |
273 | const struct modsig *modsig) | |
2fe5d6de MZ |
274 | { |
275 | return INTEGRITY_UNKNOWN; | |
276 | } | |
277 | ||
d26e1936 DK |
278 | static inline int ima_must_appraise(struct inode *inode, int mask, |
279 | enum ima_hooks func) | |
2fe5d6de MZ |
280 | { |
281 | return 0; | |
282 | } | |
283 | ||
284 | static inline void ima_update_xattr(struct integrity_iint_cache *iint, | |
285 | struct file *file) | |
286 | { | |
287 | } | |
d79d72e0 MZ |
288 | |
289 | static inline enum integrity_status ima_get_cache_status(struct integrity_iint_cache | |
4ad87a3d MZ |
290 | *iint, |
291 | enum ima_hooks func) | |
d79d72e0 MZ |
292 | { |
293 | return INTEGRITY_UNKNOWN; | |
294 | } | |
d3634d0f | 295 | |
1525b06d DK |
296 | static inline enum hash_algo |
297 | ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value, int xattr_len) | |
d3634d0f | 298 | { |
1525b06d | 299 | return ima_hash_algo; |
d3634d0f DK |
300 | } |
301 | ||
302 | static inline int ima_read_xattr(struct dentry *dentry, | |
303 | struct evm_ima_xattr_data **xattr_value) | |
304 | { | |
305 | return 0; | |
306 | } | |
307 | ||
bb543e39 | 308 | #endif /* CONFIG_IMA_APPRAISE */ |
2fe5d6de | 309 | |
9044d627 TJB |
310 | #ifdef CONFIG_IMA_APPRAISE_MODSIG |
311 | bool ima_hook_supports_modsig(enum ima_hooks func); | |
39b07096 TJB |
312 | int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, |
313 | struct modsig **modsig); | |
314 | void ima_free_modsig(struct modsig *modsig); | |
9044d627 TJB |
315 | #else |
316 | static inline bool ima_hook_supports_modsig(enum ima_hooks func) | |
317 | { | |
318 | return false; | |
319 | } | |
39b07096 TJB |
320 | |
321 | static inline int ima_read_modsig(enum ima_hooks func, const void *buf, | |
322 | loff_t buf_len, struct modsig **modsig) | |
323 | { | |
324 | return -EOPNOTSUPP; | |
325 | } | |
326 | ||
327 | static inline void ima_free_modsig(struct modsig *modsig) | |
328 | { | |
329 | } | |
9044d627 TJB |
330 | #endif /* CONFIG_IMA_APPRAISE_MODSIG */ |
331 | ||
4af4662f MZ |
332 | /* LSM based policy rules require audit */ |
333 | #ifdef CONFIG_IMA_LSM_RULES | |
334 | ||
335 | #define security_filter_rule_init security_audit_rule_init | |
336 | #define security_filter_rule_match security_audit_rule_match | |
337 | ||
338 | #else | |
339 | ||
340 | static inline int security_filter_rule_init(u32 field, u32 op, char *rulestr, | |
341 | void **lsmrule) | |
342 | { | |
343 | return -EINVAL; | |
344 | } | |
345 | ||
346 | static inline int security_filter_rule_match(u32 secid, u32 field, u32 op, | |
90462a5b | 347 | void *lsmrule) |
4af4662f MZ |
348 | { |
349 | return -EINVAL; | |
350 | } | |
5d659f28 | 351 | #endif /* CONFIG_IMA_LSM_RULES */ |
80eae209 PM |
352 | |
353 | #ifdef CONFIG_IMA_READ_POLICY | |
354 | #define POLICY_FILE_FLAGS (S_IWUSR | S_IRUSR) | |
355 | #else | |
356 | #define POLICY_FILE_FLAGS S_IWUSR | |
5d659f28 | 357 | #endif /* CONFIG_IMA_READ_POLICY */ |
80eae209 PM |
358 | |
359 | #endif /* __LINUX_IMA_H */ |