diff options
Diffstat (limited to 'security/integrity/ima/ima_main.c')
-rw-r--r-- | security/integrity/ima/ima_main.c | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index e9508d5bbfcf..149ee1119f87 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/xattr.h> | 25 | #include <linux/xattr.h> |
26 | #include <linux/ima.h> | 26 | #include <linux/ima.h> |
27 | #include <crypto/hash_info.h> | ||
27 | 28 | ||
28 | #include "ima.h" | 29 | #include "ima.h" |
29 | 30 | ||
@@ -35,11 +36,33 @@ int ima_appraise = IMA_APPRAISE_ENFORCE; | |||
35 | int ima_appraise; | 36 | int ima_appraise; |
36 | #endif | 37 | #endif |
37 | 38 | ||
38 | char *ima_hash = "sha1"; | 39 | int ima_hash_algo = HASH_ALGO_SHA1; |
40 | static int hash_setup_done; | ||
41 | |||
39 | static int __init hash_setup(char *str) | 42 | static int __init hash_setup(char *str) |
40 | { | 43 | { |
41 | if (strncmp(str, "md5", 3) == 0) | 44 | struct ima_template_desc *template_desc = ima_template_desc_current(); |
42 | ima_hash = "md5"; | 45 | int i; |
46 | |||
47 | if (hash_setup_done) | ||
48 | return 1; | ||
49 | |||
50 | if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) { | ||
51 | if (strncmp(str, "sha1", 4) == 0) | ||
52 | ima_hash_algo = HASH_ALGO_SHA1; | ||
53 | else if (strncmp(str, "md5", 3) == 0) | ||
54 | ima_hash_algo = HASH_ALGO_MD5; | ||
55 | goto out; | ||
56 | } | ||
57 | |||
58 | for (i = 0; i < HASH_ALGO__LAST; i++) { | ||
59 | if (strcmp(str, hash_algo_name[i]) == 0) { | ||
60 | ima_hash_algo = i; | ||
61 | break; | ||
62 | } | ||
63 | } | ||
64 | out: | ||
65 | hash_setup_done = 1; | ||
43 | return 1; | 66 | return 1; |
44 | } | 67 | } |
45 | __setup("ima_hash=", hash_setup); | 68 | __setup("ima_hash=", hash_setup); |
@@ -92,10 +115,9 @@ out: | |||
92 | pathname = dentry->d_name.name; | 115 | pathname = dentry->d_name.name; |
93 | 116 | ||
94 | if (send_tomtou) | 117 | if (send_tomtou) |
95 | ima_add_violation(inode, pathname, | 118 | ima_add_violation(file, pathname, "invalid_pcr", "ToMToU"); |
96 | "invalid_pcr", "ToMToU"); | ||
97 | if (send_writers) | 119 | if (send_writers) |
98 | ima_add_violation(inode, pathname, | 120 | ima_add_violation(file, pathname, |
99 | "invalid_pcr", "open_writers"); | 121 | "invalid_pcr", "open_writers"); |
100 | kfree(pathbuf); | 122 | kfree(pathbuf); |
101 | } | 123 | } |
@@ -144,9 +166,12 @@ static int process_measurement(struct file *file, const char *filename, | |||
144 | { | 166 | { |
145 | struct inode *inode = file_inode(file); | 167 | struct inode *inode = file_inode(file); |
146 | struct integrity_iint_cache *iint; | 168 | struct integrity_iint_cache *iint; |
169 | struct ima_template_desc *template_desc = ima_template_desc_current(); | ||
147 | char *pathbuf = NULL; | 170 | char *pathbuf = NULL; |
148 | const char *pathname = NULL; | 171 | const char *pathname = NULL; |
149 | int rc = -ENOMEM, action, must_appraise, _func; | 172 | int rc = -ENOMEM, action, must_appraise, _func; |
173 | struct evm_ima_xattr_data *xattr_value = NULL, **xattr_ptr = NULL; | ||
174 | int xattr_len = 0; | ||
150 | 175 | ||
151 | if (!ima_initialized || !S_ISREG(inode->i_mode)) | 176 | if (!ima_initialized || !S_ISREG(inode->i_mode)) |
152 | return 0; | 177 | return 0; |
@@ -185,7 +210,13 @@ static int process_measurement(struct file *file, const char *filename, | |||
185 | goto out_digsig; | 210 | goto out_digsig; |
186 | } | 211 | } |
187 | 212 | ||
188 | rc = ima_collect_measurement(iint, file); | 213 | if (strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) == 0) { |
214 | if (action & IMA_APPRAISE_SUBMASK) | ||
215 | xattr_ptr = &xattr_value; | ||
216 | } else | ||
217 | xattr_ptr = &xattr_value; | ||
218 | |||
219 | rc = ima_collect_measurement(iint, file, xattr_ptr, &xattr_len); | ||
189 | if (rc != 0) | 220 | if (rc != 0) |
190 | goto out_digsig; | 221 | goto out_digsig; |
191 | 222 | ||
@@ -194,9 +225,11 @@ static int process_measurement(struct file *file, const char *filename, | |||
194 | pathname = (const char *)file->f_dentry->d_name.name; | 225 | pathname = (const char *)file->f_dentry->d_name.name; |
195 | 226 | ||
196 | if (action & IMA_MEASURE) | 227 | if (action & IMA_MEASURE) |
197 | ima_store_measurement(iint, file, pathname); | 228 | ima_store_measurement(iint, file, pathname, |
229 | xattr_value, xattr_len); | ||
198 | if (action & IMA_APPRAISE_SUBMASK) | 230 | if (action & IMA_APPRAISE_SUBMASK) |
199 | rc = ima_appraise_measurement(_func, iint, file, pathname); | 231 | rc = ima_appraise_measurement(_func, iint, file, pathname, |
232 | xattr_value, xattr_len); | ||
200 | if (action & IMA_AUDIT) | 233 | if (action & IMA_AUDIT) |
201 | ima_audit_measurement(iint, pathname); | 234 | ima_audit_measurement(iint, pathname); |
202 | kfree(pathbuf); | 235 | kfree(pathbuf); |
@@ -205,6 +238,7 @@ out_digsig: | |||
205 | rc = -EACCES; | 238 | rc = -EACCES; |
206 | out: | 239 | out: |
207 | mutex_unlock(&inode->i_mutex); | 240 | mutex_unlock(&inode->i_mutex); |
241 | kfree(xattr_value); | ||
208 | if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE)) | 242 | if ((rc && must_appraise) && (ima_appraise & IMA_APPRAISE_ENFORCE)) |
209 | return -EACCES; | 243 | return -EACCES; |
210 | return 0; | 244 | return 0; |
@@ -244,9 +278,9 @@ int ima_file_mmap(struct file *file, unsigned long prot) | |||
244 | int ima_bprm_check(struct linux_binprm *bprm) | 278 | int ima_bprm_check(struct linux_binprm *bprm) |
245 | { | 279 | { |
246 | return process_measurement(bprm->file, | 280 | return process_measurement(bprm->file, |
247 | (strcmp(bprm->filename, bprm->interp) == 0) ? | 281 | (strcmp(bprm->filename, bprm->interp) == 0) ? |
248 | bprm->filename : bprm->interp, | 282 | bprm->filename : bprm->interp, |
249 | MAY_EXEC, BPRM_CHECK); | 283 | MAY_EXEC, BPRM_CHECK); |
250 | } | 284 | } |
251 | 285 | ||
252 | /** | 286 | /** |
@@ -263,8 +297,8 @@ int ima_file_check(struct file *file, int mask) | |||
263 | { | 297 | { |
264 | ima_rdwr_violation_check(file); | 298 | ima_rdwr_violation_check(file); |
265 | return process_measurement(file, NULL, | 299 | return process_measurement(file, NULL, |
266 | mask & (MAY_READ | MAY_WRITE | MAY_EXEC), | 300 | mask & (MAY_READ | MAY_WRITE | MAY_EXEC), |
267 | FILE_CHECK); | 301 | FILE_CHECK); |
268 | } | 302 | } |
269 | EXPORT_SYMBOL_GPL(ima_file_check); | 303 | EXPORT_SYMBOL_GPL(ima_file_check); |
270 | 304 | ||
@@ -294,6 +328,7 @@ static int __init init_ima(void) | |||
294 | { | 328 | { |
295 | int error; | 329 | int error; |
296 | 330 | ||
331 | hash_setup(CONFIG_IMA_DEFAULT_HASH); | ||
297 | error = ima_init(); | 332 | error = ima_init(); |
298 | if (!error) | 333 | if (!error) |
299 | ima_initialized = 1; | 334 | ima_initialized = 1; |