summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2011-08-22 15:14:18 +0200
committerMimi Zohar <zohar@linux.vnet.ibm.com>2011-09-14 21:24:52 +0200
commit566be59ab86c0e030b980645a580d683a015a483 (patch)
treec5d29c7db2f8ef93e970cb405621f59c57d01b94
parentevm: posix acls modify i_mode (diff)
downloadlinux-566be59ab86c0e030b980645a580d683a015a483.tar.xz
linux-566be59ab86c0e030b980645a580d683a015a483.zip
evm: permit mode bits to be updated
Before permitting 'security.evm' to be updated, 'security.evm' must exist and be valid. In the case that there are no existing EVM protected xattrs, it is safe for posix acls to update the mode bits. To differentiate between no 'security.evm' xattr and no xattrs used to calculate 'security.evm', this patch defines INTEGRITY_NOXATTR. Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
-rw-r--r--include/linux/integrity.h1
-rw-r--r--security/integrity/evm/evm_main.c30
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 {
INTEGRITY_PASS = 0,
INTEGRITY_FAIL,
INTEGRITY_NOLABEL,
+ INTEGRITY_NOXATTRS,
INTEGRITY_UNKNOWN,
};
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,
struct integrity_iint_cache *iint)
{
struct evm_ima_xattr_data xattr_data;
- enum integrity_status evm_status;
+ enum integrity_status evm_status = INTEGRITY_PASS;
int rc;
if (iint && iint->evm_status == INTEGRITY_PASS)
@@ -76,25 +76,18 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
xattr_value_len, xattr_data.digest);
- if (rc < 0)
- goto err_out;
+ if (rc < 0) {
+ evm_status = (rc == -ENODATA)
+ ? INTEGRITY_NOXATTRS : INTEGRITY_FAIL;
+ goto out;
+ }
xattr_data.type = EVM_XATTR_HMAC;
rc = vfs_xattr_cmp(dentry, XATTR_NAME_EVM, (u8 *)&xattr_data,
sizeof xattr_data, GFP_NOFS);
if (rc < 0)
- goto err_out;
- evm_status = INTEGRITY_PASS;
- goto out;
-
-err_out:
- switch (rc) {
- case -ENODATA: /* file not labelled */
- evm_status = INTEGRITY_NOLABEL;
- break;
- default:
- evm_status = INTEGRITY_FAIL;
- }
+ evm_status = (rc == -ENODATA)
+ ? INTEGRITY_NOLABEL : INTEGRITY_FAIL;
out:
if (iint)
iint->evm_status = evm_status;
@@ -199,7 +192,7 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
return 0;
evm_status = evm_verify_current_integrity(dentry);
if ((evm_status == INTEGRITY_PASS) ||
- (evm_status == INTEGRITY_NOLABEL))
+ (evm_status == INTEGRITY_NOXATTRS))
return 0;
return -EPERM;
}
@@ -293,7 +286,10 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
return 0;
evm_status = evm_verify_current_integrity(dentry);
- return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
+ if ((evm_status == INTEGRITY_PASS) ||
+ (evm_status == INTEGRITY_NOXATTRS))
+ return 0;
+ return -EPERM;
}
/**