@@ -319,7 +319,9 @@ int ima_appraise_measurement(enum ima_hooks func,
struct integrity_iint_cache *iint,
struct file *file, const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value,
- int xattr_len, const struct modsig *modsig);
+ int xattr_len, const struct modsig *modsig,
+ u16 file_modifiers, u8 file_actions,
+ u16 metadata_modifiers, u8 metadata_actions);
int ima_must_appraise(struct user_namespace *mnt_userns, struct inode *inode,
int mask, enum ima_hooks func);
void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file);
@@ -377,7 +377,9 @@ int ima_appraise_measurement(enum ima_hooks func,
struct integrity_iint_cache *iint,
struct file *file, const unsigned char *filename,
struct evm_ima_xattr_data *xattr_value,
- int xattr_len, const struct modsig *modsig)
+ int xattr_len, const struct modsig *modsig,
+ u16 file_modifiers, u8 file_actions,
+ u16 metadata_modifiers, u8 metadata_actions)
{
static const char op[] = "appraise_data";
const char *cause = "unknown";
@@ -387,12 +389,26 @@ int ima_appraise_measurement(enum ima_hooks func,
int rc = xattr_len;
bool try_modsig = iint->flags & IMA_MODSIG_ALLOWED && modsig;
- /* If not appraising a modsig, we need an xattr. */
- if (!(inode->i_opflags & IOP_XATTR) && !try_modsig)
+ /* We are interested only in appraisal-related flags. */
+ file_actions &= COMPACT_ACTION_IMA_APPRAISED_DIGSIG;
+ metadata_actions &= COMPACT_ACTION_IMA_APPRAISED_DIGSIG;
+
+ /* Disable DIGLIM method for appraisal if not enabled in the policy. */
+ if (!(iint->flags & IMA_USE_DIGLIM_APPRAISE)) {
+ file_actions = 0;
+ metadata_actions = 0;
+ }
+
+ /* If not appraising a modsig or using DIGLIM, we need an xattr. */
+ if (!(inode->i_opflags & IOP_XATTR) && !try_modsig &&
+ !file_actions && !metadata_actions)
return INTEGRITY_UNKNOWN;
- /* If reading the xattr failed and there's no modsig, error out. */
- if (rc <= 0 && !try_modsig) {
+ /*
+ * If reading the xattr failed, there's no modsig and the DIGLIM
+ * appraisal method is not available, error out.
+ */
+ if (rc <= 0 && !try_modsig && !file_actions && !metadata_actions) {
if (rc && rc != -ENODATA)
goto out;
@@ -420,6 +436,10 @@ int ima_appraise_measurement(enum ima_hooks func,
break;
fallthrough;
case INTEGRITY_NOLABEL: /* No security.evm xattr. */
+ if (metadata_actions) {
+ status = INTEGRITY_PASS_IMMUTABLE;
+ break;
+ }
cause = "missing-HMAC";
goto out;
case INTEGRITY_FAIL_IMMUTABLE:
@@ -455,6 +475,13 @@ int ima_appraise_measurement(enum ima_hooks func,
rc == -ENOKEY))
rc = modsig_verify(func, modsig, &status, &cause);
+ if (!xattr_value && !try_modsig && (file_actions || metadata_actions)) {
+ status = INTEGRITY_PASS;
+
+ if ((file_modifiers & (1 << COMPACT_MOD_IMMUTABLE)) ||
+ (metadata_modifiers & (1 << COMPACT_MOD_IMMUTABLE)))
+ set_bit(IMA_DIGSIG, &iint->atomic_flags);
+ }
out:
/*
* File signatures on some filesystems can not be properly verified.
@@ -416,7 +416,11 @@ static int process_measurement(struct file *file, const struct cred *cred,
inode_lock(inode);
rc = ima_appraise_measurement(func, iint, file,
pathname, xattr_value,
- xattr_len, modsig);
+ xattr_len, modsig,
+ file_modifiers,
+ file_actions,
+ metadata_modifiers,
+ metadata_actions);
inode_unlock(inode);
}
if (!rc)
Introduce a new appraisal method based on the lookup of the file and metadata digest in the DIGLIM hash table, enabled with the use_diglim directive. First pass to ima_appraise_measurement() the actions performed on the digest lists containing the found digests. Then, consider the metadata verification as successful if EVM returned the status INTEGRITY_NOLABEL (no security.evm), if the metadata digest was found in the DIGLIM hash table and at least one digest list containing it was succefully appraised with a signature. Finally, consider the file content verification as successful if there is no security.ima or appended signature, if the file or metadata digest (calculated with the actual file digest) were found in the DIGLIM hash table and at least one digest list containing it has a valid signature. Furthermore, mark the file as immutable if the COMPACT_MOD_IMMUTABLE modifier was set in the header of the digest lists containing the found digests. Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com> --- security/integrity/ima/ima.h | 4 ++- security/integrity/ima/ima_appraise.c | 37 +++++++++++++++++++++++---- security/integrity/ima/ima_main.c | 6 ++++- 3 files changed, 40 insertions(+), 7 deletions(-)