diff options
-rw-r--r-- | include/linux/integrity.h | 1 | ||||
-rw-r--r-- | security/integrity/evm/evm_main.c | 30 |
2 files changed, 14 insertions, 17 deletions
diff --git a/include/linux/integrity.h b/include/linux/integrity.h index 968443385678..a0c41256cb92 100644 --- a/include/linux/integrity.h +++ b/include/linux/integrity.h | |||
@@ -16,6 +16,7 @@ enum integrity_status { | |||
16 | INTEGRITY_PASS = 0, | 16 | INTEGRITY_PASS = 0, |
17 | INTEGRITY_FAIL, | 17 | INTEGRITY_FAIL, |
18 | INTEGRITY_NOLABEL, | 18 | INTEGRITY_NOLABEL, |
19 | INTEGRITY_NOXATTRS, | ||
19 | INTEGRITY_UNKNOWN, | 20 | INTEGRITY_UNKNOWN, |
20 | }; | 21 | }; |
21 | 22 | ||
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 73c008d047c7..92d3d99a9f7b 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c | |||
@@ -66,7 +66,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry, | |||
66 | struct integrity_iint_cache *iint) | 66 | struct integrity_iint_cache *iint) |
67 | { | 67 | { |
68 | struct evm_ima_xattr_data xattr_data; | 68 | struct evm_ima_xattr_data xattr_data; |
69 | enum integrity_status evm_status; | 69 | enum integrity_status evm_status = INTEGRITY_PASS; |
70 | int rc; | 70 | int rc; |
71 | 71 | ||
72 | if (iint && iint->evm_status == INTEGRITY_PASS) | 72 | if (iint && iint->evm_status == INTEGRITY_PASS) |
@@ -76,25 +76,18 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry, | |||
76 | 76 | ||
77 | rc = evm_calc_hmac(dentry, xattr_name, xattr_value, | 77 | rc = evm_calc_hmac(dentry, xattr_name, xattr_value, |
78 | xattr_value_len, xattr_data.digest); | 78 | xattr_value_len, xattr_data.digest); |
79 | if (rc < 0) | 79 | if (rc < 0) { |
80 | goto err_out; | 80 | evm_status = (rc == -ENODATA) |
81 | ? INTEGRITY_NOXATTRS : INTEGRITY_FAIL; | ||
82 | goto out; | ||
83 | } | ||
81 | 84 | ||
82 | xattr_data.type = EVM_XATTR_HMAC; | 85 | xattr_data.type = EVM_XATTR_HMAC; |
83 | rc = vfs_xattr_cmp(dentry, XATTR_NAME_EVM, (u8 *)&xattr_data, | 86 | rc = vfs_xattr_cmp(dentry, XATTR_NAME_EVM, (u8 *)&xattr_data, |
84 | sizeof xattr_data, GFP_NOFS); | 87 | sizeof xattr_data, GFP_NOFS); |
85 | if (rc < 0) | 88 | if (rc < 0) |
86 | goto err_out; | 89 | evm_status = (rc == -ENODATA) |
87 | evm_status = INTEGRITY_PASS; | 90 | ? INTEGRITY_NOLABEL : INTEGRITY_FAIL; |
88 | goto out; | ||
89 | |||
90 | err_out: | ||
91 | switch (rc) { | ||
92 | case -ENODATA: /* file not labelled */ | ||
93 | evm_status = INTEGRITY_NOLABEL; | ||
94 | break; | ||
95 | default: | ||
96 | evm_status = INTEGRITY_FAIL; | ||
97 | } | ||
98 | out: | 91 | out: |
99 | if (iint) | 92 | if (iint) |
100 | iint->evm_status = evm_status; | 93 | iint->evm_status = evm_status; |
@@ -199,7 +192,7 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name, | |||
199 | return 0; | 192 | return 0; |
200 | evm_status = evm_verify_current_integrity(dentry); | 193 | evm_status = evm_verify_current_integrity(dentry); |
201 | if ((evm_status == INTEGRITY_PASS) || | 194 | if ((evm_status == INTEGRITY_PASS) || |
202 | (evm_status == INTEGRITY_NOLABEL)) | 195 | (evm_status == INTEGRITY_NOXATTRS)) |
203 | return 0; | 196 | return 0; |
204 | return -EPERM; | 197 | return -EPERM; |
205 | } | 198 | } |
@@ -293,7 +286,10 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr) | |||
293 | if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))) | 286 | if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))) |
294 | return 0; | 287 | return 0; |
295 | evm_status = evm_verify_current_integrity(dentry); | 288 | evm_status = evm_verify_current_integrity(dentry); |
296 | return evm_status == INTEGRITY_PASS ? 0 : -EPERM; | 289 | if ((evm_status == INTEGRITY_PASS) || |
290 | (evm_status == INTEGRITY_NOXATTRS)) | ||
291 | return 0; | ||
292 | return -EPERM; | ||
297 | } | 293 | } |
298 | 294 | ||
299 | /** | 295 | /** |