Commit 566be59a authored by Mimi Zohar's avatar Mimi Zohar

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: default avatarMimi Zohar <zohar@us.ibm.com>
parent bf6d0f5d
...@@ -16,6 +16,7 @@ enum integrity_status { ...@@ -16,6 +16,7 @@ enum integrity_status {
INTEGRITY_PASS = 0, INTEGRITY_PASS = 0,
INTEGRITY_FAIL, INTEGRITY_FAIL,
INTEGRITY_NOLABEL, INTEGRITY_NOLABEL,
INTEGRITY_NOXATTRS,
INTEGRITY_UNKNOWN, INTEGRITY_UNKNOWN,
}; };
......
...@@ -66,7 +66,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry, ...@@ -66,7 +66,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
struct integrity_iint_cache *iint) struct integrity_iint_cache *iint)
{ {
struct evm_ima_xattr_data xattr_data; struct evm_ima_xattr_data xattr_data;
enum integrity_status evm_status; enum integrity_status evm_status = INTEGRITY_PASS;
int rc; int rc;
if (iint && iint->evm_status == INTEGRITY_PASS) if (iint && iint->evm_status == INTEGRITY_PASS)
...@@ -76,25 +76,18 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry, ...@@ -76,25 +76,18 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
rc = evm_calc_hmac(dentry, xattr_name, xattr_value, rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
xattr_value_len, xattr_data.digest); xattr_value_len, xattr_data.digest);
if (rc < 0) if (rc < 0) {
goto err_out; evm_status = (rc == -ENODATA)
? INTEGRITY_NOXATTRS : INTEGRITY_FAIL;
goto out;
}
xattr_data.type = EVM_XATTR_HMAC; xattr_data.type = EVM_XATTR_HMAC;
rc = vfs_xattr_cmp(dentry, XATTR_NAME_EVM, (u8 *)&xattr_data, rc = vfs_xattr_cmp(dentry, XATTR_NAME_EVM, (u8 *)&xattr_data,
sizeof xattr_data, GFP_NOFS); sizeof xattr_data, GFP_NOFS);
if (rc < 0) if (rc < 0)
goto err_out; evm_status = (rc == -ENODATA)
evm_status = INTEGRITY_PASS; ? INTEGRITY_NOLABEL : INTEGRITY_FAIL;
goto out;
err_out:
switch (rc) {
case -ENODATA: /* file not labelled */
evm_status = INTEGRITY_NOLABEL;
break;
default:
evm_status = INTEGRITY_FAIL;
}
out: out:
if (iint) if (iint)
iint->evm_status = evm_status; iint->evm_status = evm_status;
...@@ -199,7 +192,7 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name, ...@@ -199,7 +192,7 @@ static int evm_protect_xattr(struct dentry *dentry, const char *xattr_name,
return 0; return 0;
evm_status = evm_verify_current_integrity(dentry); evm_status = evm_verify_current_integrity(dentry);
if ((evm_status == INTEGRITY_PASS) || if ((evm_status == INTEGRITY_PASS) ||
(evm_status == INTEGRITY_NOLABEL)) (evm_status == INTEGRITY_NOXATTRS))
return 0; return 0;
return -EPERM; return -EPERM;
} }
...@@ -293,7 +286,10 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr) ...@@ -293,7 +286,10 @@ int evm_inode_setattr(struct dentry *dentry, struct iattr *attr)
if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))) if (!(ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)))
return 0; return 0;
evm_status = evm_verify_current_integrity(dentry); 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;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment