aboutsummaryrefslogtreecommitdiffstats
path: root/security/integrity/evm/evm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/integrity/evm/evm_main.c')
-rw-r--r--security/integrity/evm/evm_main.c94
1 files changed, 81 insertions, 13 deletions
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index 92d3d99a9f7b..8901501425f4 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -25,6 +25,7 @@
25int evm_initialized; 25int evm_initialized;
26 26
27char *evm_hmac = "hmac(sha1)"; 27char *evm_hmac = "hmac(sha1)";
28char *evm_hash = "sha1";
28 29
29char *evm_config_xattrnames[] = { 30char *evm_config_xattrnames[] = {
30#ifdef CONFIG_SECURITY_SELINUX 31#ifdef CONFIG_SECURITY_SELINUX
@@ -46,6 +47,29 @@ static int __init evm_set_fixmode(char *str)
46} 47}
47__setup("evm=", evm_set_fixmode); 48__setup("evm=", evm_set_fixmode);
48 49
50static int evm_find_protected_xattrs(struct dentry *dentry)
51{
52 struct inode *inode = dentry->d_inode;
53 char **xattr;
54 int error;
55 int count = 0;
56
57 if (!inode->i_op || !inode->i_op->getxattr)
58 return -EOPNOTSUPP;
59
60 for (xattr = evm_config_xattrnames; *xattr != NULL; xattr++) {
61 error = inode->i_op->getxattr(dentry, *xattr, NULL, 0);
62 if (error < 0) {
63 if (error == -ENODATA)
64 continue;
65 return error;
66 }
67 count++;
68 }
69
70 return count;
71}
72
49/* 73/*
50 * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr 74 * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
51 * 75 *
@@ -65,32 +89,72 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
65 size_t xattr_value_len, 89 size_t xattr_value_len,
66 struct integrity_iint_cache *iint) 90 struct integrity_iint_cache *iint)
67{ 91{
68 struct evm_ima_xattr_data xattr_data; 92 struct evm_ima_xattr_data *xattr_data = NULL;
93 struct evm_ima_xattr_data calc;
69 enum integrity_status evm_status = INTEGRITY_PASS; 94 enum integrity_status evm_status = INTEGRITY_PASS;
70 int rc; 95 int rc, xattr_len;
71 96
72 if (iint && iint->evm_status == INTEGRITY_PASS) 97 if (iint && iint->evm_status == INTEGRITY_PASS)
73 return iint->evm_status; 98 return iint->evm_status;
74 99
75 /* if status is not PASS, try to check again - against -ENOMEM */ 100 /* if status is not PASS, try to check again - against -ENOMEM */
76 101
77 rc = evm_calc_hmac(dentry, xattr_name, xattr_value, 102 /* first need to know the sig type */
78 xattr_value_len, xattr_data.digest); 103 rc = vfs_getxattr_alloc(dentry, XATTR_NAME_EVM, (char **)&xattr_data, 0,
79 if (rc < 0) { 104 GFP_NOFS);
80 evm_status = (rc == -ENODATA) 105 if (rc <= 0) {
81 ? INTEGRITY_NOXATTRS : INTEGRITY_FAIL; 106 if (rc == 0)
107 evm_status = INTEGRITY_FAIL; /* empty */
108 else if (rc == -ENODATA) {
109 rc = evm_find_protected_xattrs(dentry);
110 if (rc > 0)
111 evm_status = INTEGRITY_NOLABEL;
112 else if (rc == 0)
113 evm_status = INTEGRITY_NOXATTRS; /* new file */
114 }
82 goto out; 115 goto out;
83 } 116 }
84 117
85 xattr_data.type = EVM_XATTR_HMAC; 118 xattr_len = rc - 1;
86 rc = vfs_xattr_cmp(dentry, XATTR_NAME_EVM, (u8 *)&xattr_data, 119
87 sizeof xattr_data, GFP_NOFS); 120 /* check value type */
88 if (rc < 0) 121 switch (xattr_data->type) {
89 evm_status = (rc == -ENODATA) 122 case EVM_XATTR_HMAC:
90 ? INTEGRITY_NOLABEL : INTEGRITY_FAIL; 123 rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
124 xattr_value_len, calc.digest);
125 if (rc)
126 break;
127 rc = memcmp(xattr_data->digest, calc.digest,
128 sizeof(calc.digest));
129 if (rc)
130 rc = -EINVAL;
131 break;
132 case EVM_IMA_XATTR_DIGSIG:
133 rc = evm_calc_hash(dentry, xattr_name, xattr_value,
134 xattr_value_len, calc.digest);
135 if (rc)
136 break;
137 rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
138 xattr_data->digest, xattr_len,
139 calc.digest, sizeof(calc.digest));
140 if (!rc) {
141 /* we probably want to replace rsa with hmac here */
142 evm_update_evmxattr(dentry, xattr_name, xattr_value,
143 xattr_value_len);
144 }
145 break;
146 default:
147 rc = -EINVAL;
148 break;
149 }
150
151 if (rc)
152 evm_status = (rc == -ENODATA) ?
153 INTEGRITY_NOXATTRS : INTEGRITY_FAIL;
91out: 154out:
92 if (iint) 155 if (iint)
93 iint->evm_status = evm_status; 156 iint->evm_status = evm_status;
157 kfree(xattr_data);
94 return evm_status; 158 return evm_status;
95} 159}
96 160
@@ -354,6 +418,8 @@ static int __init init_evm(void)
354 printk(KERN_INFO "EVM: Error registering secfs\n"); 418 printk(KERN_INFO "EVM: Error registering secfs\n");
355 goto err; 419 goto err;
356 } 420 }
421
422 return 0;
357err: 423err:
358 return error; 424 return error;
359} 425}
@@ -363,6 +429,8 @@ static void __exit cleanup_evm(void)
363 evm_cleanup_secfs(); 429 evm_cleanup_secfs();
364 if (hmac_tfm) 430 if (hmac_tfm)
365 crypto_free_shash(hmac_tfm); 431 crypto_free_shash(hmac_tfm);
432 if (hash_tfm)
433 crypto_free_shash(hash_tfm);
366} 434}
367 435
368/* 436/*