summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Jung Bauermann <bauerman@linux.ibm.com>2019-06-11 02:28:08 -0400
committerMimi Zohar <zohar@linux.ibm.com>2019-06-30 17:54:41 -0400
commit650b29dbdf2caf7db27cdc8bfa8fc009b28a6ce3 (patch)
tree41585db527639befc8ae4ea09619ea40078b0fde
parent337619eb44ef663d329c5c19efd18488ce7de492 (diff)
integrity: Introduce struct evm_xattr
Even though struct evm_ima_xattr_data includes a fixed-size array to hold a SHA1 digest, most of the code ignores the array and uses the struct to mean "type indicator followed by data of unspecified size" and tracks the real size of what the struct represents in a separate length variable. The only exception to that is the EVM code, which correctly uses the definition of struct evm_ima_xattr_data. So make this explicit in the code by removing the length specification from the array in struct evm_ima_xattr_data. Also, change the name of the element from digest to data since in most places the array doesn't hold a digest. A separate struct evm_xattr is introduced, with the original definition of evm_ima_xattr_data to be used in the places that actually expect that definition, specifically the EVM HMAC code. Signed-off-by: Thiago Jung Bauermann <bauerman@linux.ibm.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
-rw-r--r--security/integrity/evm/evm_main.c8
-rw-r--r--security/integrity/ima/ima_appraise.c7
-rw-r--r--security/integrity/integrity.h6
3 files changed, 14 insertions, 7 deletions
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index b6d9f14bc234..588f22f1b5bd 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -169,7 +169,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
169 /* check value type */ 169 /* check value type */
170 switch (xattr_data->type) { 170 switch (xattr_data->type) {
171 case EVM_XATTR_HMAC: 171 case EVM_XATTR_HMAC:
172 if (xattr_len != sizeof(struct evm_ima_xattr_data)) { 172 if (xattr_len != sizeof(struct evm_xattr)) {
173 evm_status = INTEGRITY_FAIL; 173 evm_status = INTEGRITY_FAIL;
174 goto out; 174 goto out;
175 } 175 }
@@ -179,7 +179,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
179 xattr_value_len, &digest); 179 xattr_value_len, &digest);
180 if (rc) 180 if (rc)
181 break; 181 break;
182 rc = crypto_memneq(xattr_data->digest, digest.digest, 182 rc = crypto_memneq(xattr_data->data, digest.digest,
183 SHA1_DIGEST_SIZE); 183 SHA1_DIGEST_SIZE);
184 if (rc) 184 if (rc)
185 rc = -EINVAL; 185 rc = -EINVAL;
@@ -523,7 +523,7 @@ int evm_inode_init_security(struct inode *inode,
523 const struct xattr *lsm_xattr, 523 const struct xattr *lsm_xattr,
524 struct xattr *evm_xattr) 524 struct xattr *evm_xattr)
525{ 525{
526 struct evm_ima_xattr_data *xattr_data; 526 struct evm_xattr *xattr_data;
527 int rc; 527 int rc;
528 528
529 if (!evm_key_loaded() || !evm_protected_xattr(lsm_xattr->name)) 529 if (!evm_key_loaded() || !evm_protected_xattr(lsm_xattr->name))
@@ -533,7 +533,7 @@ int evm_inode_init_security(struct inode *inode,
533 if (!xattr_data) 533 if (!xattr_data)
534 return -ENOMEM; 534 return -ENOMEM;
535 535
536 xattr_data->type = EVM_XATTR_HMAC; 536 xattr_data->data.type = EVM_XATTR_HMAC;
537 rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest); 537 rc = evm_init_hmac(inode, lsm_xattr, xattr_data->digest);
538 if (rc < 0) 538 if (rc < 0)
539 goto out; 539 goto out;
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 2f6536ab69e8..18bbe753421a 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -168,7 +168,8 @@ enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
168 return sig->hash_algo; 168 return sig->hash_algo;
169 break; 169 break;
170 case IMA_XATTR_DIGEST_NG: 170 case IMA_XATTR_DIGEST_NG:
171 ret = xattr_value->digest[0]; 171 /* first byte contains algorithm id */
172 ret = xattr_value->data[0];
172 if (ret < HASH_ALGO__LAST) 173 if (ret < HASH_ALGO__LAST)
173 return ret; 174 return ret;
174 break; 175 break;
@@ -176,7 +177,7 @@ enum hash_algo ima_get_hash_algo(struct evm_ima_xattr_data *xattr_value,
176 /* this is for backward compatibility */ 177 /* this is for backward compatibility */
177 if (xattr_len == 21) { 178 if (xattr_len == 21) {
178 unsigned int zero = 0; 179 unsigned int zero = 0;
179 if (!memcmp(&xattr_value->digest[16], &zero, 4)) 180 if (!memcmp(&xattr_value->data[16], &zero, 4))
180 return HASH_ALGO_MD5; 181 return HASH_ALGO_MD5;
181 else 182 else
182 return HASH_ALGO_SHA1; 183 return HASH_ALGO_SHA1;
@@ -275,7 +276,7 @@ int ima_appraise_measurement(enum ima_hooks func,
275 /* xattr length may be longer. md5 hash in previous 276 /* xattr length may be longer. md5 hash in previous
276 version occupied 20 bytes in xattr, instead of 16 277 version occupied 20 bytes in xattr, instead of 16
277 */ 278 */
278 rc = memcmp(&xattr_value->digest[hash_start], 279 rc = memcmp(&xattr_value->data[hash_start],
279 iint->ima_hash->digest, 280 iint->ima_hash->digest,
280 iint->ima_hash->length); 281 iint->ima_hash->length);
281 else 282 else
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h
index 7de59f44cba3..88a29f72a74f 100644
--- a/security/integrity/integrity.h
+++ b/security/integrity/integrity.h
@@ -79,6 +79,12 @@ enum evm_ima_xattr_type {
79 79
80struct evm_ima_xattr_data { 80struct evm_ima_xattr_data {
81 u8 type; 81 u8 type;
82 u8 data[];
83} __packed;
84
85/* Only used in the EVM HMAC code. */
86struct evm_xattr {
87 struct evm_ima_xattr_data data;
82 u8 digest[SHA1_DIGEST_SIZE]; 88 u8 digest[SHA1_DIGEST_SIZE];
83} __packed; 89} __packed;
84 90