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