All of lore.kernel.org
 help / color / mirror / Atom feed
From: Roberto Sassu <roberto.sassu@huaweicloud.com>
To: corbet@lwn.net, zohar@linux.ibm.com, dmitry.kasatkin@gmail.com,
	eric.snowberg@oracle.com, paul@paul-moore.com, jmorris@namei.org,
	serge@hallyn.com
Cc: linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-integrity@vger.kernel.org,
	linux-security-module@vger.kernel.org, wufan@linux.microsoft.com,
	pbrobinson@gmail.com, zbyszek@in.waw.pl, hch@lst.de,
	mjg59@srcf.ucam.org, pmatilai@redhat.com, jannh@google.com,
	dhowells@redhat.com, jikos@kernel.org, mkoutny@suse.com,
	ppavlu@suse.com, petr.vorel@gmail.com,
	petrtesarik@huaweicloud.com, mzerqung@0pointer.de,
	kgold@linux.ibm.com, Roberto Sassu <roberto.sassu@huawei.com>
Subject: [RFC][PATCH 7/8] ima: Use digest cache for appraisal
Date: Wed, 14 Feb 2024 15:35:23 +0100	[thread overview]
Message-ID: <20240214143525.2205481-8-roberto.sassu@huaweicloud.com> (raw)
In-Reply-To: <20240214143525.2205481-1-roberto.sassu@huaweicloud.com>

From: Roberto Sassu <roberto.sassu@huawei.com>

Similarly to measurement, enable the new appraisal style too using digest
caches.

Instead of verifying individual file signatures, verify the signature of
lists of digests and search calculated file digests in those lists.

The benefits are that signed lists of digests already exist (e.g. RPM
package headers), although their format needs to be supported by the
digest_cache LSM, and appraisal with digest lists is computationally much
less expensive than with individual file signatures (see the performance
evaluation of the digest_cache LSM).

As for measurement, pass the AND of the policy mask and the digest list
verification mask to ima_appraise_measurement().

If EVM is disabled or the file does not have any protected xattr
(evm_verifyxattr() returns INTEGRITY_UNKNOWN or INTEGRITY_NOXATTRS), the
other appraisal methods (xattr and modsig) are not available, and the AND
of the masks has the IMA_DIGEST_CACHE_APPRAISE_CONTENT flag set, mark the
file as successfully appraised (i.e. set the integrity status to
INTEGRITY_PASS and return zero).

Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
---
 security/integrity/ima/ima.h          |  6 ++++--
 security/integrity/ima/ima_appraise.c | 31 +++++++++++++++++++++------
 security/integrity/ima/ima_main.c     |  3 ++-
 3 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index cf04f5a22234..36faf2bc81b0 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -433,7 +433,8 @@ int ima_check_blacklist(struct ima_iint_cache *iint,
 int ima_appraise_measurement(enum ima_hooks func, struct ima_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,
+			     u64 digest_cache_mask);
 int ima_must_appraise(struct mnt_idmap *idmap, struct inode *inode,
 		      int mask, enum ima_hooks func);
 void ima_update_xattr(struct ima_iint_cache *iint, struct file *file);
@@ -458,7 +459,8 @@ static inline int ima_appraise_measurement(enum ima_hooks func,
 					   const unsigned char *filename,
 					   struct evm_ima_xattr_data *xattr_value,
 					   int xattr_len,
-					   const struct modsig *modsig)
+					   const struct modsig *modsig,
+					   u8 digest_cache_mask)
 {
 	return INTEGRITY_UNKNOWN;
 }
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
index 27ccc9a2c09f..dcea88d502a9 100644
--- a/security/integrity/ima/ima_appraise.c
+++ b/security/integrity/ima/ima_appraise.c
@@ -478,7 +478,8 @@ int ima_check_blacklist(struct ima_iint_cache *iint,
 int ima_appraise_measurement(enum ima_hooks func, struct ima_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,
+			     u64 digest_cache_mask)
 {
 	static const char op[] = "appraise_data";
 	const char *cause = "unknown";
@@ -488,12 +489,19 @@ int ima_appraise_measurement(enum ima_hooks func, struct ima_iint_cache *iint,
 	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)
+	/*
+	 * If not appraising a modsig/there is no digest cache match, we need
+	 * an xattr.
+	 */
+	if (!(inode->i_opflags & IOP_XATTR) && !try_modsig &&
+	    !digest_cache_mask)
 		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 and there's no modsig/digest cache match,
+	 * error out.
+	 */
+	if (rc <= 0 && !try_modsig && !digest_cache_mask) {
 		if (rc && rc != -ENODATA)
 			goto out;
 
@@ -524,8 +532,11 @@ int ima_appraise_measurement(enum ima_hooks func, struct ima_iint_cache *iint,
 	case INTEGRITY_UNKNOWN:
 		break;
 	case INTEGRITY_NOXATTRS:	/* No EVM protected xattrs. */
-		/* It's fine not to have xattrs when using a modsig. */
-		if (try_modsig)
+		/*
+		 * It's fine not to have xattrs when using a modsig or the
+		 * digest cache.
+		 */
+		if (try_modsig || digest_cache_mask)
 			break;
 		fallthrough;
 	case INTEGRITY_NOLABEL:		/* No security.evm xattr. */
@@ -555,6 +566,12 @@ int ima_appraise_measurement(enum ima_hooks func, struct ima_iint_cache *iint,
 	     rc == -ENOKEY))
 		rc = modsig_verify(func, modsig, &status, &cause);
 
+	if (!xattr_value && !try_modsig &&
+	    (digest_cache_mask & IMA_DIGEST_CACHE_APPRAISE_CONTENT)) {
+		status = INTEGRITY_PASS;
+		rc = 0;
+	}
+
 out:
 	/*
 	 * File signatures on some filesystems can not be properly verified.
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 48a09747ae7a..a66522a22cbc 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -400,7 +400,8 @@ 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,
+						      allow_mask);
 			inode_unlock(inode);
 		}
 		if (!rc)
-- 
2.34.1


  parent reply	other threads:[~2024-02-14 14:37 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-14 14:35 [RFC][PATCH 0/8] ima: Integrate with digest_cache LSM Roberto Sassu
2024-02-14 14:35 ` [RFC][PATCH 1/8] ima: Introduce hook DIGEST_LIST_CHECK Roberto Sassu
2024-02-14 14:35 ` [RFC][PATCH 2/8] ima: Nest iint mutex for DIGEST_LIST_CHECK hook Roberto Sassu
2024-03-07 19:42   ` Mimi Zohar
2024-03-08  8:00     ` Roberto Sassu
2024-02-14 14:35 ` [RFC][PATCH 3/8] ima: Add digest_cache policy keyword Roberto Sassu
2024-03-07 19:43   ` Mimi Zohar
2024-03-08  9:05     ` Roberto Sassu
2024-03-08 13:41       ` Mimi Zohar
2024-02-14 14:35 ` [RFC][PATCH 4/8] ima: Add digest_cache_measure and digest_cache_appraise boot-time policies Roberto Sassu
2024-03-07 20:17   ` Mimi Zohar
2024-03-08 10:36     ` Roberto Sassu
2024-03-08 14:23       ` Mimi Zohar
2024-03-11 13:01   ` Mimi Zohar
2024-02-14 14:35 ` [RFC][PATCH 5/8] ima: Record IMA verification result of digest lists in digest cache Roberto Sassu
2024-03-11 14:00   ` Mimi Zohar
2024-02-14 14:35 ` [RFC][PATCH 6/8] ima: Use digest cache for measurement Roberto Sassu
2024-03-08 16:08   ` Mimi Zohar
2024-03-08 16:27     ` Roberto Sassu
2024-02-14 14:35 ` Roberto Sassu [this message]
2024-02-14 14:35 ` [RFC][PATCH 8/8] ima: Detect if digest cache changed since last measurement/appraisal Roberto Sassu
2024-03-08 17:35   ` Mimi Zohar
2024-03-11  9:11     ` Roberto Sassu
2024-03-11 12:19       ` Mimi Zohar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240214143525.2205481-8-roberto.sassu@huaweicloud.com \
    --to=roberto.sassu@huaweicloud.com \
    --cc=corbet@lwn.net \
    --cc=dhowells@redhat.com \
    --cc=dmitry.kasatkin@gmail.com \
    --cc=eric.snowberg@oracle.com \
    --cc=hch@lst.de \
    --cc=jannh@google.com \
    --cc=jikos@kernel.org \
    --cc=jmorris@namei.org \
    --cc=kgold@linux.ibm.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=mjg59@srcf.ucam.org \
    --cc=mkoutny@suse.com \
    --cc=mzerqung@0pointer.de \
    --cc=paul@paul-moore.com \
    --cc=pbrobinson@gmail.com \
    --cc=petr.vorel@gmail.com \
    --cc=petrtesarik@huaweicloud.com \
    --cc=pmatilai@redhat.com \
    --cc=ppavlu@suse.com \
    --cc=roberto.sassu@huawei.com \
    --cc=serge@hallyn.com \
    --cc=wufan@linux.microsoft.com \
    --cc=zbyszek@in.waw.pl \
    --cc=zohar@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.