summary refs log tree commit diff
path: root/security
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2011-08-11 01:22:30 -0400
committerMimi Zohar <zohar@linux.vnet.ibm.com>2011-09-14 15:24:51 -0400
commita924ce0b35875ef9512135b46a32f4150fd700b2 (patch)
tree0e01ac679790fe96c03b341b2670a2ed9c56a122 /security
parentfb88c2b6cbb1265a8bef60694699b37f5cd4ba76 (diff)
downloadlinux-a924ce0b35875ef9512135b46a32f4150fd700b2.tar.gz
evm: limit verifying current security.evm integrity
evm_protect_xattr unnecessarily validates the current security.evm
integrity, before updating non-evm protected extended attributes
and other file metadata. This patch limits validating the current
security.evm integrity to evm protected metadata.

Signed-off-by: Mimi Zohar <zohar@us.ibm.com>
Diffstat (limited to 'security')
-rw-r--r--security/integrity/evm/evm_main.c58
1 files changed, 24 insertions, 34 deletions
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
index f0127e536f84..7d4247535f9e 100644
--- a/security/integrity/evm/evm_main.c
+++ b/security/integrity/evm/evm_main.c
@@ -159,21 +159,6 @@ enum integrity_status evm_verifyxattr(struct dentry *dentry,
 EXPORT_SYMBOL_GPL(evm_verifyxattr);
 
 /*
- * evm_protect_xattr - protect the EVM extended attribute
- *
- * Prevent security.evm from being modified or removed.
- */
-static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
-			     const void *xattr_value, size_t xattr_value_len)
-{
-	if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
-		if (!capable(CAP_SYS_ADMIN))
-			return -EPERM;
-	}
-	return 0;
-}
-
-/*
  * evm_verify_current_integrity - verify the dentry's metadata integrity
  * @dentry: pointer to the affected dentry
  *
@@ -189,6 +174,26 @@ static enum integrity_status evm_verify_current_integrity(struct dentry *dentry)
 	return evm_verify_hmac(dentry, NULL, NULL, 0, NULL);
 }
 
+/*
+ * evm_protect_xattr - protect the EVM extended attribute
+ *
+ * Prevent security.evm from being modified or removed.
+ */
+static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
+			     const void *xattr_value, size_t xattr_value_len)
+{
+	enum integrity_status evm_status;
+
+	if (strcmp(xattr_name, XATTR_NAME_EVM) == 0) {
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+	} else if (!evm_protected_xattr(xattr_name))
+		return 0;
+
+	evm_status = evm_verify_current_integrity(dentry);
+	return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
+}
+
 /**
  * evm_inode_setxattr - protect the EVM extended attribute
  * @dentry: pointer to the affected dentry
@@ -202,16 +207,8 @@ static enum integrity_status evm_verify_current_integrity(struct dentry *dentry)
 int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
 		       const void *xattr_value, size_t xattr_value_len)
 {
-
-	enum integrity_status evm_status;
-	int ret;
-
-	ret = evm_protect_xattr(dentry, xattr_name, xattr_value,
-				xattr_value_len);
-	if (ret)
-		return ret;
-	evm_status = evm_verify_current_integrity(dentry);
-	return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
+	return evm_protect_xattr(dentry, xattr_name, xattr_value,
+				 xattr_value_len);
 }
 
 /**
@@ -224,14 +221,7 @@ int evm_inode_setxattr(struct dentry *dentry, const char *xattr_name,
  */
 int evm_inode_removexattr(struct dentry *dentry, const char *xattr_name)
 {
-	enum integrity_status evm_status;
-	int ret;
-
-	ret = evm_protect_xattr(dentry, xattr_name, NULL, 0);
-	if (ret)
-		return ret;
-	evm_status = evm_verify_current_integrity(dentry);
-	return evm_status == INTEGRITY_PASS ? 0 : -EPERM;
+	return evm_protect_xattr(dentry, xattr_name, NULL, 0);
 }
 
 /**
@@ -286,7 +276,7 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
 	unsigned int ia_valid = attr->ia_valid;
 	enum integrity_status evm_status;
 
-	if (ia_valid & ~(ATTR_MODE | ATTR_UID | ATTR_GID))
+	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;