Linux Integrity Measurement development
 help / color / mirror / Atom feed
* [PATCH v7 06/11] tpm2-sessions: Remove 'attributes' from tpm_buf_append_auth
From: Jarkko Sakkinen @ 2025-11-27 13:54 UTC (permalink / raw)
  To: linux-integrity
  Cc: ross.philipson, Jonathan McDowell, Stefano Garzarella,
	Jarkko Sakkinen, Jonathan McDowell, Peter Huewe, Jarkko Sakkinen,
	Jason Gunthorpe, Roberto Sassu, Mimi Zohar, linux-kernel
In-Reply-To: <20251127135445.2141241-1-jarkko@kernel.org>

From: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>

In a previous bug fix, 'attributes' was added by mistake to
tpm_buf_append_auth(). Remove the parameter.

Fixes: 27184f8905ba ("tpm: Opt-in in disable PCR integrity protection")
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>
Reviewed-by: Jonathan McDowell <noodles@meta.com>
---
v6:
- No changes.
v5:
- No changes.
v4:
- No changes.
v3:
- No changes
v2:
- Uncorrupt the patch.
---
 drivers/char/tpm/tpm2-cmd.c      | 2 +-
 drivers/char/tpm/tpm2-sessions.c | 5 ++---
 include/linux/tpm.h              | 2 +-
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 1393bfbeca64..ceffa3bd2b5c 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -206,7 +206,7 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
 		tpm_buf_append_hmac_session(chip, &buf, 0, NULL, 0);
 	} else {
 		tpm_buf_append_handle(chip, &buf, pcr_idx);
-		tpm_buf_append_auth(chip, &buf, 0, NULL, 0);
+		tpm_buf_append_auth(chip, &buf, NULL, 0);
 	}
 
 	tpm_buf_append_u32(&buf, chip->nr_allocated_banks);
diff --git a/drivers/char/tpm/tpm2-sessions.c b/drivers/char/tpm/tpm2-sessions.c
index 6d03c224e6b2..13f019d1312a 100644
--- a/drivers/char/tpm/tpm2-sessions.c
+++ b/drivers/char/tpm/tpm2-sessions.c
@@ -266,7 +266,7 @@ void tpm_buf_append_name(struct tpm_chip *chip, struct tpm_buf *buf,
 EXPORT_SYMBOL_GPL(tpm_buf_append_name);
 
 void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf,
-			 u8 attributes, u8 *passphrase, int passphrase_len)
+			 u8 *passphrase, int passphrase_len)
 {
 	/* offset tells us where the sessions area begins */
 	int offset = buf->handles * 4 + TPM_HEADER_SIZE;
@@ -327,8 +327,7 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
 #endif
 
 	if (!tpm2_chip_auth(chip)) {
-		tpm_buf_append_auth(chip, buf, attributes, passphrase,
-				    passphrase_len);
+		tpm_buf_append_auth(chip, buf, passphrase, passphrase_len);
 		return;
 	}
 
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index e5fc7b73de2d..5acf6422e2b9 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -531,7 +531,7 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf,
 				 u8 attributes, u8 *passphrase,
 				 int passphraselen);
 void tpm_buf_append_auth(struct tpm_chip *chip, struct tpm_buf *buf,
-			 u8 attributes, u8 *passphrase, int passphraselen);
+			 u8 *passphrase, int passphraselen);
 static inline void tpm_buf_append_hmac_session_opt(struct tpm_chip *chip,
 						   struct tpm_buf *buf,
 						   u8 attributes,
-- 
2.52.0


^ permalink raw reply related

* [PATCH v7 05/11] KEYS: trusted: Use tpm_ret_to_err() in trusted_tpm2
From: Jarkko Sakkinen @ 2025-11-27 13:54 UTC (permalink / raw)
  To: linux-integrity
  Cc: ross.philipson, Jonathan McDowell, Stefano Garzarella,
	Jarkko Sakkinen, James Bottomley, Jarkko Sakkinen, Mimi Zohar,
	David Howells, Paul Moore, James Morris, Serge E. Hallyn,
	keyrings, linux-security-module, linux-kernel
In-Reply-To: <20251127135445.2141241-1-jarkko@kernel.org>

From: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>

Use tpm_ret_to_err() to transmute TPM return codes in trusted_tpm2.

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>
Acked-by: Stefano Garzarella <sgarzare@redhat.com>
---
v6:
- No changes.
v5:
- No changes.
v4:
- No changes.
v3:
- No changes.
v2:
- New patch split out from the fix.
---
 security/keys/trusted-keys/trusted_tpm2.c | 26 ++++++-----------------
 1 file changed, 7 insertions(+), 19 deletions(-)

diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index 00bc1afb32c8..c9973ac46041 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -331,25 +331,19 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
 	}
 
 	blob_len = tpm2_key_encode(payload, options, &buf.data[offset], blob_len);
+	if (blob_len < 0)
+		rc = blob_len;
 
 out:
 	tpm_buf_destroy(&sized);
 	tpm_buf_destroy(&buf);
 
-	if (rc > 0) {
-		if (tpm2_rc_value(rc) == TPM2_RC_HASH)
-			rc = -EINVAL;
-		else
-			rc = -EPERM;
-	}
-	if (blob_len < 0)
-		rc = blob_len;
-	else
+	if (!rc)
 		payload->blob_len = blob_len;
 
 out_put:
 	tpm_put_ops(chip);
-	return rc;
+	return tpm_ret_to_err(rc);
 }
 
 /**
@@ -453,10 +447,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
 out:
 	tpm_buf_destroy(&buf);
 
-	if (rc > 0)
-		rc = -EPERM;
-
-	return rc;
+	return tpm_ret_to_err(rc);
 }
 
 /**
@@ -519,8 +510,6 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
 	tpm_buf_fill_hmac_session(chip, &buf);
 	rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
 	rc = tpm_buf_check_hmac_response(chip, &buf, rc);
-	if (rc > 0)
-		rc = -EPERM;
 
 	if (!rc) {
 		data_len = be16_to_cpup(
@@ -553,7 +542,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
 
 out:
 	tpm_buf_destroy(&buf);
-	return rc;
+	return tpm_ret_to_err(rc);
 }
 
 /**
@@ -585,6 +574,5 @@ int tpm2_unseal_trusted(struct tpm_chip *chip,
 
 out:
 	tpm_put_ops(chip);
-
-	return rc;
+	return tpm_ret_to_err(rc);
 }
-- 
2.52.0


^ permalink raw reply related

* [PATCH v7 04/11] KEYS: trusted: Fix memory leak in tpm2_load()
From: Jarkko Sakkinen @ 2025-11-27 13:54 UTC (permalink / raw)
  To: linux-integrity
  Cc: ross.philipson, Jonathan McDowell, Stefano Garzarella,
	Jarkko Sakkinen, stable, James Bottomley, Mimi Zohar,
	David Howells, Paul Moore, James Morris, Serge E. Hallyn,
	keyrings, linux-security-module, linux-kernel
In-Reply-To: <20251127135445.2141241-1-jarkko@kernel.org>

tpm2_load() allocates a blob indirectly via tpm2_key_decode() but it is
not freed in all failure paths. Address this with a scope-based cleanup
helper __free(). For legacy blobs, the implicit de-allocation is gets
disable by no_free_ptr().

Cc: stable@vger.kernel.org # v5.13+
Fixes: f2219745250f ("security: keys: trusted: use ASN.1 TPM2 key format for the blobs")
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
v7:
- Fix compiler warning.
v6:
- A new patch in this version.
---
 security/keys/trusted-keys/trusted_tpm2.c | 24 +++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index 3205732fb4b7..00bc1afb32c8 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -98,9 +98,8 @@ struct tpm2_key_context {
 	u32 priv_len;
 };
 
-static int tpm2_key_decode(struct trusted_key_payload *payload,
-			   struct trusted_key_options *options,
-			   u8 **buf)
+static void *tpm2_key_decode(struct trusted_key_payload *payload,
+			     struct trusted_key_options *options)
 {
 	int ret;
 	struct tpm2_key_context ctx;
@@ -111,16 +110,15 @@ static int tpm2_key_decode(struct trusted_key_payload *payload,
 	ret = asn1_ber_decoder(&tpm2key_decoder, &ctx, payload->blob,
 			       payload->blob_len);
 	if (ret < 0)
-		return ret;
+		return ERR_PTR(ret);
 
 	if (ctx.priv_len + ctx.pub_len > MAX_BLOB_SIZE)
-		return -EINVAL;
+		return ERR_PTR(-EINVAL);
 
 	blob = kmalloc(ctx.priv_len + ctx.pub_len + 4, GFP_KERNEL);
 	if (!blob)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
-	*buf = blob;
 	options->keyhandle = ctx.parent;
 
 	memcpy(blob, ctx.priv, ctx.priv_len);
@@ -128,7 +126,7 @@ static int tpm2_key_decode(struct trusted_key_payload *payload,
 
 	memcpy(blob, ctx.pub, ctx.pub_len);
 
-	return 0;
+	return blob;
 }
 
 int tpm2_key_parent(void *context, size_t hdrlen,
@@ -372,6 +370,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
 			 struct trusted_key_options *options,
 			 u32 *blob_handle)
 {
+	u8 *blob_ref __free(kfree) = NULL;
 	struct tpm_buf buf;
 	unsigned int private_len;
 	unsigned int public_len;
@@ -380,11 +379,14 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
 	int rc;
 	u32 attrs;
 
-	rc = tpm2_key_decode(payload, options, &blob);
-	if (rc) {
+	blob = tpm2_key_decode(payload, options);
+	if (IS_ERR(blob)) {
 		/* old form */
 		blob = payload->blob;
 		payload->old_format = 1;
+	} else {
+		/* Bind to cleanup: */
+		blob_ref = blob;
 	}
 
 	/* new format carries keyhandle but old format doesn't */
@@ -449,8 +451,6 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
 			(__be32 *) &buf.data[TPM_HEADER_SIZE]);
 
 out:
-	if (blob != payload->blob)
-		kfree(blob);
 	tpm_buf_destroy(&buf);
 
 	if (rc > 0)
-- 
2.52.0


^ permalink raw reply related

* [PATCH v7 03/11] KEYS: trusted: remove redundant instance of tpm2_hash_map
From: Jarkko Sakkinen @ 2025-11-27 13:54 UTC (permalink / raw)
  To: linux-integrity
  Cc: ross.philipson, Jonathan McDowell, Stefano Garzarella,
	Jarkko Sakkinen, Peter Huewe, Jason Gunthorpe, James Bottomley,
	Mimi Zohar, David Howells, Paul Moore, James Morris,
	Serge E. Hallyn, linux-kernel, keyrings, linux-security-module
In-Reply-To: <20251127135445.2141241-1-jarkko@kernel.org>

Trusted keys duplicates tpm2_hash_map from TPM driver internals. Implement
and export `tpm2_find_hash_alg()` in order to address this glitch, and
replace redundant code block with a call this new function.

Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
v7:
- A new patch.
---
 drivers/char/tpm/tpm2-cmd.c               | 19 +++++++++++++++--
 include/linux/tpm.h                       |  7 ++-----
 security/keys/trusted-keys/trusted_tpm2.c | 25 +++++------------------
 3 files changed, 24 insertions(+), 27 deletions(-)

diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 97501c567c34..1393bfbeca64 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -18,7 +18,10 @@ static bool disable_pcr_integrity;
 module_param(disable_pcr_integrity, bool, 0444);
 MODULE_PARM_DESC(disable_pcr_integrity, "Disable integrity protection of TPM2_PCR_Extend");
 
-static struct tpm2_hash tpm2_hash_map[] = {
+static struct {
+	unsigned int crypto_id;
+	unsigned int alg_id;
+} tpm2_hash_map[] = {
 	{HASH_ALGO_SHA1, TPM_ALG_SHA1},
 	{HASH_ALGO_SHA256, TPM_ALG_SHA256},
 	{HASH_ALGO_SHA384, TPM_ALG_SHA384},
@@ -26,6 +29,18 @@ static struct tpm2_hash tpm2_hash_map[] = {
 	{HASH_ALGO_SM3_256, TPM_ALG_SM3_256},
 };
 
+int tpm2_find_hash_alg(unsigned int crypto_id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++)
+		if (crypto_id == tpm2_hash_map[i].crypto_id)
+			return tpm2_hash_map[i].alg_id;
+
+	return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(tpm2_find_hash_alg);
+
 int tpm2_get_timeouts(struct tpm_chip *chip)
 {
 	chip->timeout_a = msecs_to_jiffies(TPM2_TIMEOUT_A);
@@ -490,7 +505,7 @@ static int tpm2_init_bank_info(struct tpm_chip *chip, u32 bank_index)
 	for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) {
 		enum hash_algo crypto_algo = tpm2_hash_map[i].crypto_id;
 
-		if (bank->alg_id != tpm2_hash_map[i].tpm_id)
+		if (bank->alg_id != tpm2_hash_map[i].alg_id)
 			continue;
 
 		bank->digest_size = hash_digest_size[crypto_algo];
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 0e9e043f728c..e5fc7b73de2d 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -410,11 +410,6 @@ enum tpm2_session_attributes {
 	TPM2_SA_AUDIT			= BIT(7),
 };
 
-struct tpm2_hash {
-	unsigned int crypto_id;
-	unsigned int tpm_id;
-};
-
 int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal);
 void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal);
 int tpm_buf_init_sized(struct tpm_buf *buf);
@@ -465,6 +460,7 @@ static inline ssize_t tpm_ret_to_err(ssize_t ret)
 
 #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
 
+unsigned int tpm2_alg_to_crypto_id(unsigned int alg_id);
 extern int tpm_is_tpm2(struct tpm_chip *chip);
 extern __must_check int tpm_try_get_ops(struct tpm_chip *chip);
 extern void tpm_put_ops(struct tpm_chip *chip);
@@ -477,6 +473,7 @@ extern int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
 extern int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max);
 extern struct tpm_chip *tpm_default_chip(void);
 void tpm2_flush_context(struct tpm_chip *chip, u32 handle);
+int tpm2_find_hash_alg(unsigned int crypto_id);
 
 static inline void tpm_buf_append_empty_auth(struct tpm_buf *buf, u32 handle)
 {
diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index 024be262702f..3205732fb4b7 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -18,14 +18,6 @@
 
 #include "tpm2key.asn1.h"
 
-static struct tpm2_hash tpm2_hash_map[] = {
-	{HASH_ALGO_SHA1, TPM_ALG_SHA1},
-	{HASH_ALGO_SHA256, TPM_ALG_SHA256},
-	{HASH_ALGO_SHA384, TPM_ALG_SHA384},
-	{HASH_ALGO_SHA512, TPM_ALG_SHA512},
-	{HASH_ALGO_SM3_256, TPM_ALG_SM3_256},
-};
-
 static u32 tpm2key_oid[] = { 2, 23, 133, 10, 1, 5 };
 
 static int tpm2_key_encode(struct trusted_key_payload *payload,
@@ -244,24 +236,17 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
 	off_t offset = TPM_HEADER_SIZE;
 	struct tpm_buf buf, sized;
 	int blob_len = 0;
-	u32 hash;
+	int hash;
 	u32 flags;
-	int i;
 	int rc;
 
-	for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) {
-		if (options->hash == tpm2_hash_map[i].crypto_id) {
-			hash = tpm2_hash_map[i].tpm_id;
-			break;
-		}
-	}
-
-	if (i == ARRAY_SIZE(tpm2_hash_map))
-		return -EINVAL;
-
 	if (!options->keyhandle)
 		return -EINVAL;
 
+	hash = tpm2_find_hash_alg(options->hash);
+	if (hash)
+		return hash;
+
 	rc = tpm_try_get_ops(chip);
 	if (rc)
 		return rc;
-- 
2.52.0


^ permalink raw reply related

* [PATCH v7 02/11] tpm: Use -EPERM as fallback error code in tpm_ret_to_err
From: Jarkko Sakkinen @ 2025-11-27 13:54 UTC (permalink / raw)
  To: linux-integrity
  Cc: ross.philipson, Jonathan McDowell, Stefano Garzarella,
	Jarkko Sakkinen, Peter Huewe, Jarkko Sakkinen, Jason Gunthorpe,
	linux-kernel
In-Reply-To: <20251127135445.2141241-1-jarkko@kernel.org>

From: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>

Using -EFAULT as the tpm_ret_to_err() fallback error code causes makes it
incompatible on how trusted keys transmute TPM return codes.

Change the fallback as -EPERM in order to gain compatibility with trusted
keys. In addition, map TPM_RC_HASH to -EINVAL in order to be compatible
with tpm2_seal_trusted() return values.

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
---
v6:
- No changes.
v5:
- No changes.
v4:
- No changes.
v3:
- Removed fixes tag as it hardly categorizes as a bug fix.
v2:
- Split trusted_tpm2 change to a separate patch.
---
 include/linux/tpm.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index eb0ff071bcae..0e9e043f728c 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -456,8 +456,10 @@ static inline ssize_t tpm_ret_to_err(ssize_t ret)
 		return 0;
 	case TPM2_RC_SESSION_MEMORY:
 		return -ENOMEM;
+	case TPM2_RC_HASH:
+		return -EINVAL;
 	default:
-		return -EFAULT;
+		return -EPERM;
 	}
 }
 
-- 
2.52.0


^ permalink raw reply related

* [PATCH v7 01/11] tpm: Cap the number of PCR banks
From: Jarkko Sakkinen @ 2025-11-27 13:54 UTC (permalink / raw)
  To: linux-integrity
  Cc: ross.philipson, Jonathan McDowell, Stefano Garzarella,
	Jarkko Sakkinen, Roberto Sassu, Jonathan McDowell, Peter Huewe,
	Jarkko Sakkinen, Jason Gunthorpe, linux-kernel
In-Reply-To: <20251127135445.2141241-1-jarkko@kernel.org>

From: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>

tpm2_get_pcr_allocation() does not cap any upper limit for the number of
banks. Cap the limit to eight banks so that out of bounds values coming
from external I/O cause on only limited harm.

Cc: Roberto Sassu <roberto.sassu@huawei.com>
Fixes: bcfff8384f6c ("tpm: dynamically allocate the allocated_banks array")
Reviewed-By: Jonathan McDowell <noodles@meta.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>
---
v7:
- In Ryzen desktop there is total three banks so yep, eight is probably
  much safer bet than four banks. Fixed the commit message as per remark
  from Jonathan:

  https://lore.kernel.org/linux-integrity/aPYg1N0TvrkG6AJI@earth.li/#t

  And with that added also reviewed-by.
v6
- No changes.
v5:
- No changes.
v4:
- Revert spurious changes from include/linux/tpm.h.
- Increase TPM2_MAX_BANKS to 8.
- Rename TPM2_MAX_BANKS as TPM2_MAX_PCR_BANKS for the sake of clarity.
v3:
- Wrote a more clear commit message.
- Fixed pr_err() message.
v2:
- A new patch.
---
 drivers/char/tpm/tpm-chip.c | 13 +++++++++----
 drivers/char/tpm/tpm.h      |  1 -
 drivers/char/tpm/tpm1-cmd.c | 25 -------------------------
 drivers/char/tpm/tpm2-cmd.c |  8 +++-----
 include/linux/tpm.h         |  8 +++++---
 5 files changed, 17 insertions(+), 38 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index e25daf2396d3..6cb25862688f 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -559,14 +559,19 @@ static int tpm_add_hwrng(struct tpm_chip *chip)
 
 static int tpm_get_pcr_allocation(struct tpm_chip *chip)
 {
-	int rc;
+	int rc = 0;
 
 	if (tpm_is_firmware_upgrade(chip))
 		return 0;
 
-	rc = (chip->flags & TPM_CHIP_FLAG_TPM2) ?
-	     tpm2_get_pcr_allocation(chip) :
-	     tpm1_get_pcr_allocation(chip);
+	if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) {
+		chip->allocated_banks[0].alg_id = TPM_ALG_SHA1;
+		chip->allocated_banks[0].digest_size = hash_digest_size[HASH_ALGO_SHA1];
+		chip->allocated_banks[0].crypto_id = HASH_ALGO_SHA1;
+		chip->nr_allocated_banks = 1;
+	} else {
+		rc = tpm2_get_pcr_allocation(chip);
+	}
 
 	if (rc > 0)
 		return -ENODEV;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 2726bd38e5ac..a37712c02e44 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -252,7 +252,6 @@ int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf);
 ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
 		    const char *desc, size_t min_cap_length);
 int tpm1_get_random(struct tpm_chip *chip, u8 *out, size_t max);
-int tpm1_get_pcr_allocation(struct tpm_chip *chip);
 unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
 int tpm_pm_suspend(struct device *dev);
 int tpm_pm_resume(struct device *dev);
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 11088bda4e68..708bc553437b 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -786,28 +786,3 @@ int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr)
 
 	return rc;
 }
-
-/**
- * tpm1_get_pcr_allocation() - initialize the allocated bank
- * @chip: TPM chip to use.
- *
- * The function initializes the SHA1 allocated bank to extend PCR
- *
- * Return:
- * * 0 on success,
- * * < 0 on error.
- */
-int tpm1_get_pcr_allocation(struct tpm_chip *chip)
-{
-	chip->allocated_banks = kcalloc(1, sizeof(*chip->allocated_banks),
-					GFP_KERNEL);
-	if (!chip->allocated_banks)
-		return -ENOMEM;
-
-	chip->allocated_banks[0].alg_id = TPM_ALG_SHA1;
-	chip->allocated_banks[0].digest_size = hash_digest_size[HASH_ALGO_SHA1];
-	chip->allocated_banks[0].crypto_id = HASH_ALGO_SHA1;
-	chip->nr_allocated_banks = 1;
-
-	return 0;
-}
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 7d77f6fbc152..97501c567c34 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -538,11 +538,9 @@ ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
 
 	nr_possible_banks = be32_to_cpup(
 		(__be32 *)&buf.data[TPM_HEADER_SIZE + 5]);
-
-	chip->allocated_banks = kcalloc(nr_possible_banks,
-					sizeof(*chip->allocated_banks),
-					GFP_KERNEL);
-	if (!chip->allocated_banks) {
+	if (nr_possible_banks > TPM2_MAX_PCR_BANKS) {
+		pr_err("tpm: unexpected number of banks: %u > %u",
+		       nr_possible_banks, TPM2_MAX_PCR_BANKS);
 		rc = -ENOMEM;
 		goto out;
 	}
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index dc0338a783f3..eb0ff071bcae 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -26,7 +26,9 @@
 #include <crypto/aes.h>
 
 #define TPM_DIGEST_SIZE 20	/* Max TPM v1.2 PCR size */
-#define TPM_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
+
+#define TPM2_MAX_DIGEST_SIZE	SHA512_DIGEST_SIZE
+#define TPM2_MAX_PCR_BANKS	8
 
 struct tpm_chip;
 struct trusted_key_payload;
@@ -68,7 +70,7 @@ enum tpm2_curves {
 
 struct tpm_digest {
 	u16 alg_id;
-	u8 digest[TPM_MAX_DIGEST_SIZE];
+	u8 digest[TPM2_MAX_DIGEST_SIZE];
 } __packed;
 
 struct tpm_bank_info {
@@ -189,7 +191,7 @@ struct tpm_chip {
 	unsigned int groups_cnt;
 
 	u32 nr_allocated_banks;
-	struct tpm_bank_info *allocated_banks;
+	struct tpm_bank_info allocated_banks[TPM2_MAX_PCR_BANKS];
 #ifdef CONFIG_ACPI
 	acpi_handle acpi_dev_handle;
 	char ppi_version[TPM_PPI_VERSION_LEN + 1];
-- 
2.52.0


^ permalink raw reply related

* [PATCH v7 00/11] Prepare TPM driver for Trenchboot
From: Jarkko Sakkinen @ 2025-11-27 13:54 UTC (permalink / raw)
  To: linux-integrity
  Cc: ross.philipson, Jonathan McDowell, Stefano Garzarella,
	Jarkko Sakkinen

Overview
========

Start preparing TPM driver for Trenchboot by decoupling tpm_buf from
driver and memory allocation.

Backlog (of stuff that will end up to a follow-up patch sets):

1. Static flat duration table for TPM 1.2. Such feature already landed
   in v6.17 for TPM 2.0. We probably can figure out some sane roof
   values for the legacy standard, right? This allows to share more
   code "via data".
2. Not a blocker for sending subsequent versions of Trenchboot patch set
   but we could look at slicing tpm_tis code at some point of future.
   It could be even that redundant parts could be "merged" after the
   feature lands but this is neither a promise (depends on how things
   look overall).

This patch set does not do a lot heavy-lifting but is beefed enough that
it is better not fatten it up too much anymore. Sane buffering is a
great starting point.

v7:
- Fixed reported issues.
v6:
- Fixed a memory leak that I found trom trusted keys.
v5:
- Order sobs correctly.
- Fixed a minor glitch in 9/9.
v4:
- PCR patch has been removed because it does not fly without Trenchboot
  context.
v3:
- I think 6.19 is a better goal for this and thus expanded the series to
  be a generic Trenchboot enablers series. This version also consolidates
  my two separate ongoing series.
v2:
- While including fixes from v1, this patch set has a refocus in order to
  do minimal changes to make code base more compatible  Trenchboot.

Jarkko Sakkinen (11):
  tpm: Cap the number of PCR banks
  tpm: Use -EPERM as fallback error code in tpm_ret_to_err
  KEYS: trusted: remove redundant instance of tpm2_hash_map
  KEYS: trusted: Fix memory leak in tpm2_load()
  KEYS: trusted: Use tpm_ret_to_err() in trusted_tpm2
  tpm2-sessions: Remove 'attributes' from tpm_buf_append_auth
  tpm2-sessions: Unmask tpm_buf_append_hmac_session()
  KEYS: trusted: Open code tpm2_buf_append()
  tpm-buf: unify TPM_BUF_BOUNDARY_ERROR and TPM_BUF_OVERFLOW
  tpm-buf: Remove chip parameter from tpm_buf_append_handle
  tpm-buf: Enable managed and stack allocations.

 drivers/char/tpm/tpm-buf.c                | 143 ++++++----
 drivers/char/tpm/tpm-chip.c               |  13 +-
 drivers/char/tpm/tpm-sysfs.c              |  21 +-
 drivers/char/tpm/tpm.h                    |   2 -
 drivers/char/tpm/tpm1-cmd.c               | 185 +++++-------
 drivers/char/tpm/tpm2-cmd.c               | 332 +++++++++++-----------
 drivers/char/tpm/tpm2-sessions.c          | 129 ++++-----
 drivers/char/tpm/tpm2-space.c             |  44 ++-
 drivers/char/tpm/tpm_vtpm_proxy.c         |  30 +-
 include/linux/tpm.h                       |  74 ++---
 security/keys/trusted-keys/trusted_tpm1.c |  36 +--
 security/keys/trusted-keys/trusted_tpm2.c | 291 ++++++++-----------
 12 files changed, 584 insertions(+), 716 deletions(-)

-- 
2.52.0


^ permalink raw reply

* Re: [PATCH v3 1/4] shell: Add tst_sudo.c helper
From: Petr Vorel @ 2025-11-27 12:55 UTC (permalink / raw)
  To: Li Wang
  Cc: ltp, Mimi Zohar, linux-integrity, selinux, Cyril Hrubis,
	Jan Stancek
In-Reply-To: <CAEemH2e6ivP0rzfTBp5LnZ8n-oe7moqfHszgs2QyYVMUTUQ_wQ@mail.gmail.com>

> On Thu, Nov 27, 2025 at 7:57 PM Li Wang <liwang@redhat.com> wrote:

> > Hi Petr,

> > I feel that the filename tst_sudo.c is a bit misleading. The helper
> > doesn’t
> > replicate sudo behavior (authentication, privilege escalation), it simply
> > drops from root to a fixed UID/GID before executing a command.

> > So readers may expect a “sudo-like” elevation wrapper when, however
> > it’s a privilege-dropping trampoline.

Thanks, makes sense.

> > What about renaming it to:
> >   tst_runas.c,
> >   tst_runas_nobody.c, or
> >   tst_drop_privs.c?

> Personally, I prefer the tst_runas_nody.c because it reflects the
> default privilege,
> but due it supports the more env so contains "su" maybe better:
>   tst_su_switch.c, tst_su_cmd.c

I'd be ok with tst_su.c, but sure tst_su_cmd.c is ok as well.
I'll wait little longer for feedback from others.

Kind regards,
Petr

^ permalink raw reply

* Re: [RFC v1 0/1] Implement IMA Event Log Trimming
From: Roberto Sassu @ 2025-11-27  9:45 UTC (permalink / raw)
  To: Gregory Lumen
  Cc: Anirudh Venkataramanan, linux-integrity, Mimi Zohar,
	Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Paul Moore,
	James Morris, Serge E . Hallyn, linux-security-module,
	Steven Chen, Lakshmi Ramasubramanian, Sush Shringarputale
In-Reply-To: <bbafa611-3a6c-5cf8-631c-20f72f651d9@linux.microsoft.com>

On Wed, 2025-11-26 at 15:40 -0800, Gregory Lumen wrote:
> Greetings Roberto,
> 
> If I may chime in a bit:
> 
> > The only way to make the verification of measurements list snapshots
> > work is that the verification state is stored outside the system to
> > evaluate (which can be assumed to be trusted), so that you are sure
> > that the system is not advancing the PCR starting value by itself.
> 
> You are correct; to make the described approach work, an external source 
> of trust is required in order to detect unexpected or unauthorized 
> trimming of the event log (for example, by signing the trim-to PCR values 
> from the previous verification/attestation cycle). This should be true 
> regardless of the mechanism of trimming. More generally, I will go so far 
> as to suggest that any attempt to attest the integrity of a system using 
> IMA will likely fall into one of two general approaches: either the entire 
> IMA event log is retained (either in kernel or user space) from boot and 
> claims of system integrity are built by validating and examining the 
> entire log for signs of tampering, or an external source of trust is 
> introduced to allow incremental validation and examination of the log. 
> Other more innovative approaches may exist, but we make no such claims.
> 
> I will also say that it should be possible to implement either approach to 
> attestation (retaining the entire log, or relying on an external source of 
> trust) with any sane implementation for IMA log trimming.
> 
> As for our proposed implementation, storing the starting PCR values in the 
> kernel preserving the ability for any arbitrary user space entity to 
> validate the retained portion of the IMA event log against the TPM PCRs at 
> any time, without requiring awareness of other user space mechanisms 
> implemented by other entities that may be initiating IMA trimming 
> operations. My personal sense is that this capability is worth preserving, 
> but it is entirely possible the general consensus is that the value 
> offered does not balance against the additional technical complexity when 
> compared to simpler alternatives (discussed in a moment). To stress the 
> point, this capability would only enable validation of the integrity of 
> the retained portion of the event log and its continuity with the PCRs, 
> and could not be used to make any claims as to the overall integrity of 
> the system since, as you observed, an attacker who has successfully 
> compromised the system could simply trim the event log in order to discard 
> evidence of the compromise.

Hi Gregory

all you said can be implemented by maintaining the PCR starting value
outside the system, in a trusted entity. This would allow the
functionality you are hoping for to validate the retained portion of
the measurement list.

Keeping the PCR starting value in the kernel has the potential of
misleading users that this is an information they can rely on. I would
rather prefer to not run in such risk.

> If the ability to validate the retained portion of the IMA event log is 
> not worth designing for, we could instead go with a simpler "Trim-to-N" 
> approach, where the user space interface allows for the specification of 
> an absolute index into the IMA log to be used as the trim position (as 
> opposed to using calculated PCR values to indicate trim position in our 
> current proposal). To protect against unexpected behavior in the event of 

From implementation point of view, it looks much simpler to me to
specify N relative to the current measurement list.

> concurrent trims, index counting would need to be fixed (hence absolute) 
> such that index 0 would always refer to the very first entry written 
> during boot, even if that entry has already been trimmed, with the number 
> of trimmed entries (and thus starting index of the retained log) exposed 
> to use space via a pseudo-file.

In my draft patch [1] (still need to support trimming N entries instead
of the full measurement list), the risk of concurrent trims does not
exist because opening of the snapshot interface is exclusive (no one
else can request trimming concurrently).

If a more elaborated contention of remote attestation agent is
required, that could be done at user space level. I'm hoping to keep in
the kernel only the minimum code necessary for the remote attestation
to work.

Roberto

[1] https://github.com/robertosassu/linux/commit/b0bd002b6caa9d5d4f4d0db2a041b1fd91f33f8a

> With such a trim approach, it should be possible to implement either 
> general attestation approach: retaining the entire log (copy the log to 
> user space, then trim the copied entries), or relying on an external 
> source of trust (quote, determine the log index corresponding to the quote 
> plus PCRs, trim, then securely store the trim position/starting PCRs for 
> future cycles).
> 
> -Gregory Lumen


^ permalink raw reply

* [PATCH v3 4/4] ima_conditionals.sh: Split test by request
From: Petr Vorel @ 2025-11-27  8:26 UTC (permalink / raw)
  To: ltp
  Cc: Petr Vorel, Mimi Zohar, linux-integrity, selinux, Cyril Hrubis,
	Jan Stancek, Li Wang
In-Reply-To: <20251127082638.224110-1-pvorel@suse.cz>

This helps to run all testcases on systems without CONFIG_IMA_WRITE_POLICY=y
(disabled by default in mainline, therefore disabled for some distros,
e.g. openSUSE Tumbleweed), if SUT reboots.

Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
 runtest/ima                                   |  5 +-
 .../integrity/ima/tests/ima_conditionals.sh   | 67 ++++++++++++-------
 2 files changed, 46 insertions(+), 26 deletions(-)

diff --git a/runtest/ima b/runtest/ima
index 01942eefa3..c8d0c6801e 100644
--- a/runtest/ima
+++ b/runtest/ima
@@ -6,5 +6,8 @@ ima_violations ima_violations.sh
 ima_keys ima_keys.sh
 ima_kexec ima_kexec.sh
 ima_selinux ima_selinux.sh
-ima_conditionals ima_conditionals.sh
+ima_conditionals_uid ima_conditionals.sh -r uid
+ima_conditionals_fowner ima_conditionals.sh -r fowner
+ima_conditionals_gid ima_conditionals.sh -r gid
+ima_conditionals_fgroup ima_conditionals.sh -r fgroup
 evm_overlay evm_overlay.sh
diff --git a/testcases/kernel/security/integrity/ima/tests/ima_conditionals.sh b/testcases/kernel/security/integrity/ima/tests/ima_conditionals.sh
index e290dcdaaa..8eed0b6a9d 100755
--- a/testcases/kernel/security/integrity/ima/tests/ima_conditionals.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_conditionals.sh
@@ -11,35 +11,66 @@
 
 TST_NEEDS_CMDS="cat chgrp chown"
 TST_SETUP="setup"
-TST_CNT=1
+TST_OPTS="r:"
+TST_USAGE="usage"
+TST_PARSE_ARGS="parse_args"
+REQUEST="uid"
+
+parse_args()
+{
+	REQUEST="$2"
+}
+
+usage()
+{
+	cat << EOF
+usage: $0 [-r <uid|fowner|gid|fgroup>]
+
+OPTIONS
+-r	Specify the request to be measured. One of:
+	uid, fowner, gid, fgroup
+	Default: uid
+EOF
+}
 
 setup()
 {
+	case "$REQUEST" in
+	fgroup|fowner|gid|uid)
+		tst_res TINFO "request '$REQUEST'"
+		;;
+	*) tst_brk TBROK "Invalid -r '$REQUEST', use: -r <uid|fowner|gid|fgroup>";;
+	esac
+
 	if check_need_signed_policy; then
 		tst_brk TCONF "policy have to be signed"
 	fi
 }
 
-verify_measurement()
+test()
 {
+	# needs to be checked each run (not in setup)
+	require_policy_writable
+
 	local request="$1"
-	local user="nobody"
 	local test_file="$PWD/test.txt"
 	local cmd="cat $test_file > /dev/null"
-
 	local value="$TST_USR_UID"
-	[ "$request" = 'gid' -o "$request" = 'fgroup' ] && value="$TST_USR_GID"
 
-	# needs to be checked each run (not in setup)
-	require_policy_writable
+	if [ "$REQUEST" = 'gid' -o "$REQUEST" = 'fgroup' ]; then
+		if tst_kvcmp -lt 5.16; then
+			tst_brk TCONF "gid and fgroup options require kernel 5.16 or newer"
+		fi
+		value="$TST_USR_GID"
+	fi
 
 	ROD rm -f $test_file
 
-	tst_res TINFO "verify measuring user files when requested via $request"
-	ROD echo "measure $request=$value" \> $IMA_POLICY
-	ROD echo "$(cat /proc/uptime) $request test" \> $test_file
+	tst_res TINFO "verify measuring user files when requested via $REQUEST"
+	ROD echo "measure $REQUEST=$value" \> $IMA_POLICY
+	ROD echo "$(cat /proc/uptime) $REQUEST test" \> $test_file
 
-	case "$request" in
+	case "$REQUEST" in
 	fgroup)
 		chgrp $TST_USR_GID $test_file
 		sh -c "$cmd"
@@ -49,24 +80,10 @@ verify_measurement()
 		sh -c "$cmd"
 		;;
 	gid|uid) tst_sudo sh -c "$cmd";;
-	*) tst_brk TBROK "Invalid res type '$1'";;
 	esac
 
 	ima_check $test_file
 }
 
-test1()
-{
-	verify_measurement uid
-	verify_measurement fowner
-
-	if tst_kvcmp -lt 5.16; then
-		tst_brk TCONF "gid and fgroup options require kernel 5.16 or newer"
-	fi
-
-	verify_measurement gid
-	verify_measurement fgroup
-}
-
 . ima_setup.sh
 tst_run
-- 
2.51.0


^ permalink raw reply related

* [PATCH v3 3/4] ima_{conditionals,measurements}.sh: Use tst_sudo
From: Petr Vorel @ 2025-11-27  8:26 UTC (permalink / raw)
  To: ltp
  Cc: Petr Vorel, Mimi Zohar, linux-integrity, selinux, Cyril Hrubis,
	Jan Stancek, Li Wang
In-Reply-To: <20251127082638.224110-1-pvorel@suse.cz>

Replace 'sudo' and 'sg' with 'tst_sudo'.

This not only removes 'sudo' external dependency, but it s required
because new releases of many distros (e.g. Debian, openSUSE Tumbleweed,
SLES, ...) switched shell for 'nobody' user from /bin/bash (or /bin/sh)
to /usr/sbin/nologin. That effectively disables using 'sudo', 'su', 'sg':

    ima_conditionals 1 TINFO: verify measuring user files when requested via uid
    sudo: Account expired or PAM config lacks an "account" section for sudo, contact your system administrator
    sudo: a password is required

Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
 .../integrity/ima/tests/ima_conditionals.sh         | 13 ++++++-------
 .../integrity/ima/tests/ima_measurements.sh         | 11 ++---------
 2 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/testcases/kernel/security/integrity/ima/tests/ima_conditionals.sh b/testcases/kernel/security/integrity/ima/tests/ima_conditionals.sh
index ba19176039..e290dcdaaa 100755
--- a/testcases/kernel/security/integrity/ima/tests/ima_conditionals.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_conditionals.sh
@@ -9,7 +9,7 @@
 # gid and fgroup options test kernel commit 40224c41661b ("ima: add gid
 # support") from v5.16.
 
-TST_NEEDS_CMDS="cat chgrp chown id sg sudo"
+TST_NEEDS_CMDS="cat chgrp chown"
 TST_SETUP="setup"
 TST_CNT=1
 
@@ -27,8 +27,8 @@ verify_measurement()
 	local test_file="$PWD/test.txt"
 	local cmd="cat $test_file > /dev/null"
 
-	local value="$(id -u $user)"
-	[ "$request" = 'gid' -o "$request" = 'fgroup' ] && value="$(id -g $user)"
+	local value="$TST_USR_UID"
+	[ "$request" = 'gid' -o "$request" = 'fgroup' ] && value="$TST_USR_GID"
 
 	# needs to be checked each run (not in setup)
 	require_policy_writable
@@ -41,15 +41,14 @@ verify_measurement()
 
 	case "$request" in
 	fgroup)
-		chgrp $user $test_file
+		chgrp $TST_USR_GID $test_file
 		sh -c "$cmd"
 		;;
 	fowner)
-		chown $user $test_file
+		chown $TST_USR_UID $test_file
 		sh -c "$cmd"
 		;;
-	gid) sg $user "sh -c '$cmd'";;
-	uid) sudo -n -u $user sh -c "$cmd";;
+	gid|uid) tst_sudo sh -c "$cmd";;
 	*) tst_brk TBROK "Invalid res type '$1'";;
 	esac
 
diff --git a/testcases/kernel/security/integrity/ima/tests/ima_measurements.sh b/testcases/kernel/security/integrity/ima/tests/ima_measurements.sh
index 60350f3926..30bfe3e629 100755
--- a/testcases/kernel/security/integrity/ima/tests/ima_measurements.sh
+++ b/testcases/kernel/security/integrity/ima/tests/ima_measurements.sh
@@ -68,30 +68,23 @@ test2()
 
 test3()
 {
-	local user="nobody"
 	local dir="$PWD/user"
 	local file="$dir/test.txt"
 	local cmd="grep $file $ASCII_MEASUREMENTS"
 
 	# Default policy does not measure user files
 	tst_res TINFO "verify not measuring user files"
-	tst_check_cmds sudo || return
 
 	if [ "$IMA_MISSING_POLICY_CONTENT" = 1 ]; then
 		tst_res TCONF "test requires specific policy, try load it with LTP_IMA_LOAD_POLICY=1"
 		return
 	fi
 
-	if ! id $user >/dev/null 2>/dev/null; then
-		tst_res TCONF "missing system user $user (wrong installation)"
-		return
-	fi
-
 	[ -d "$dir" ] || mkdir -m 0700 $dir
-	chown $user $dir
+	chown $TST_USR_UID $dir
 	cd $dir
 	# need to read file to get updated $ASCII_MEASUREMENTS
-	sudo -n -u $user sh -c "echo $(cat /proc/uptime) user file > $file; cat $file > /dev/null"
+	tst_sudo sh -c "echo $(cat /proc/uptime) user file > $file; cat $file > /dev/null"
 	cd ..
 
 	if ! tst_rod "$cmd" 2> /dev/null; then
-- 
2.51.0


^ permalink raw reply related

* [PATCH v3 2/4] tst_test.sh: Add TST_USR_{G,U}ID variables
From: Petr Vorel @ 2025-11-27  8:26 UTC (permalink / raw)
  To: ltp
  Cc: Petr Vorel, Mimi Zohar, linux-integrity, selinux, Cyril Hrubis,
	Jan Stancek, Li Wang
In-Reply-To: <20251127082638.224110-1-pvorel@suse.cz>

Add TST_USR_{G,U}ID variables with the default values from tst_sudo.c.

These can be used as a default values for tests which use tst_sudo and
need to know UID/GID for other commands.

It will be used in LTP IMA tests.

Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
 testcases/lib/tst_sudo.c  | 1 +
 testcases/lib/tst_test.sh | 6 +++++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/testcases/lib/tst_sudo.c b/testcases/lib/tst_sudo.c
index e8d5d8dd9d..e937828273 100644
--- a/testcases/lib/tst_sudo.c
+++ b/testcases/lib/tst_sudo.c
@@ -3,6 +3,7 @@
  * Copyright (c) 2025 Petr Vorel <pvorel@suse.cz>
  */
 
+/* update also tst_test.sh */
 #define LTP_USR_UID 65534
 #define LTP_USR_GID 65534
 
diff --git a/testcases/lib/tst_test.sh b/testcases/lib/tst_test.sh
index 4be10a4f94..49f282d7c8 100644
--- a/testcases/lib/tst_test.sh
+++ b/testcases/lib/tst_test.sh
@@ -17,6 +17,10 @@ export TST_ITERATIONS=1
 export TST_TMPDIR_RHOST=0
 export TST_LIB_LOADED=1
 
+# see testcases/lib/tst_sudo.c
+export TST_USR_UID="${LTP_USR_UID:-65534}"
+export TST_USR_GID="${LTP_USR_GID:-65534}"
+
 . tst_ansi_color.sh
 . tst_security.sh
 
@@ -689,7 +693,7 @@ tst_run()
 			CHECKPOINT_WAKE2|CHECKPOINT_WAKE_AND_WAIT);;
 			DEV_EXTRA_OPTS|DEV_FS_OPTS|FORMAT_DEVICE|MOUNT_DEVICE);;
 			SKIP_FILESYSTEMS|SKIP_IN_LOCKDOWN|SKIP_IN_SECUREBOOT);;
-			DEVICE_SIZE);;
+			DEVICE_SIZE|USR_UID|USR_GID);;
 			*) tst_res TWARN "Reserved variable TST_$_tst_i used!";;
 			esac
 		done
-- 
2.51.0


^ permalink raw reply related

* [PATCH v3 1/4] shell: Add tst_sudo.c helper
From: Petr Vorel @ 2025-11-27  8:26 UTC (permalink / raw)
  To: ltp
  Cc: Petr Vorel, Mimi Zohar, linux-integrity, selinux, Cyril Hrubis,
	Jan Stancek, Li Wang
In-Reply-To: <20251127082638.224110-1-pvorel@suse.cz>

It will be used in LTP IMA tests. Not only it removes external
dependency, but also fixes problem when 'nobody' user is not possible to
use due using /usr/sbin/nologin shell.

Suggested-by: Jan Stancek <jstancek@redhat.com>
Signed-off-by: Petr Vorel <pvorel@suse.cz>
---
 doc/users/setup_tests.rst |  4 ++++
 testcases/lib/.gitignore  |  1 +
 testcases/lib/Makefile    |  2 +-
 testcases/lib/tst_sudo.c  | 50 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 testcases/lib/tst_sudo.c

diff --git a/doc/users/setup_tests.rst b/doc/users/setup_tests.rst
index 38976f3b0a..9c49852830 100644
--- a/doc/users/setup_tests.rst
+++ b/doc/users/setup_tests.rst
@@ -71,6 +71,10 @@ users.
    * - LTP_IMA_LOAD_POLICY
      - Load IMA example policy, see :master:`testcases/kernel/security/integrity/ima/README.md`.
 
+   * - LTP_USR_UID, LTP_USR_GID
+     - Set UID and GID of ``nobody`` user for :doc:`../developers/api_shell_tests`,
+       see :master:`testcases/lib/tst_sudo.c`.
+
    * - LTP_VIRT_OVERRIDE
      - Overrides virtual machine detection in the test library. Setting it to
        empty string, tells the library that system is not a virtual machine.
diff --git a/testcases/lib/.gitignore b/testcases/lib/.gitignore
index 19d7c67bbe..785d638cba 100644
--- a/testcases/lib/.gitignore
+++ b/testcases/lib/.gitignore
@@ -26,3 +26,4 @@
 /tst_res_
 /tst_run_shell
 /tst_remaining_runtime
+/tst_sudo
diff --git a/testcases/lib/Makefile b/testcases/lib/Makefile
index 2309a42a3d..9be9946057 100644
--- a/testcases/lib/Makefile
+++ b/testcases/lib/Makefile
@@ -17,6 +17,6 @@ MAKE_TARGETS		:= tst_sleep tst_random tst_checkpoint tst_rod tst_kvcmp\
 			   tst_get_median tst_hexdump tst_get_free_pids tst_timeout_kill\
 			   tst_check_kconfigs tst_cgctl tst_fsfreeze tst_ns_create tst_ns_exec\
 			   tst_ns_ifmove tst_lockdown_enabled tst_secureboot_enabled tst_res_\
-			   tst_run_shell tst_remaining_runtime
+			   tst_run_shell tst_remaining_runtime tst_sudo
 
 include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/testcases/lib/tst_sudo.c b/testcases/lib/tst_sudo.c
new file mode 100644
index 0000000000..e8d5d8dd9d
--- /dev/null
+++ b/testcases/lib/tst_sudo.c
@@ -0,0 +1,50 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2025 Petr Vorel <pvorel@suse.cz>
+ */
+
+#define LTP_USR_UID 65534
+#define LTP_USR_GID 65534
+
+#define TST_NO_DEFAULT_MAIN
+#include "tst_test.h"
+
+static void print_help(void)
+{
+	fprintf(stderr, "Usage: %s cmd [args] ...\n", __FILE__);
+	fprintf(stderr, "Usage: %s cmd [-h] print help\n\n", __FILE__);
+
+	fprintf(stderr, "Environment Variables\n");
+	fprintf(stderr, "LTP_USR_UID: UID of 'nobody' user, defaults %d\n",
+			LTP_USR_UID);
+	fprintf(stderr, "LTP_USR_GID: GID of 'nobody' user, defaults %d\n",
+			LTP_USR_GID);
+}
+
+int main(int argc, char *argv[])
+{
+	if (argc < 2 || !strcmp(argv[1], "-h")) {
+		print_help();
+		return 1;
+	}
+
+	unsigned uid = LTP_USR_UID, gid = LTP_USR_GID;
+
+	char *uid_env = getenv(TST_TO_STR_(LTP_USR_UID));
+	char *gid_env = getenv(TST_TO_STR_(LTP_USR_GID));
+
+	if (uid_env)
+		uid = SAFE_STRTOL(uid_env, 1, INT_MAX);
+
+	if (gid_env)
+		gid = SAFE_STRTOL(gid_env, 1, INT_MAX);
+
+	tst_res(TINFO, "UID: %d, GID: %d", uid, gid);
+	SAFE_SETGROUPS(0, NULL);
+	SAFE_SETRESGID(gid, gid, gid);
+	SAFE_SETRESUID(uid, uid, uid);
+
+	SAFE_CMD((const char * const *)&argv[1], NULL, NULL);
+
+	return 0;
+}
-- 
2.51.0


^ permalink raw reply related

* [PATCH v3 0/4] tst_sudo.c, ima_{conditionals, measurements}.sh enhancements
From: Petr Vorel @ 2025-11-27  8:26 UTC (permalink / raw)
  To: ltp
  Cc: Petr Vorel, Mimi Zohar, linux-integrity, selinux, Cyril Hrubis,
	Jan Stancek, Li Wang

From: Petr Vorel <petr.vorel@gmail.com>

Changes v2->v3:
Rebased due conflict when 69b28f1f78 ("shell: Add support for runtime")
was merged.

Links to v2:
https://lore.kernel.org/ltp/20251121152111.10419-1-pvorel@suse.cz/
https://patchwork.ozlabs.org/project/ltp/list/?series=483104&state=*

Changes v1->v2:
Main change is implementing LTP binary tst_sudo.c as suggested by Jan
Stancek [1] instead of creating new user.

Links to v1:
https://lore.kernel.org/ltp/20251002083701.315334-1-pvorel@suse.cz/
https://patchwork.ozlabs.org/project/ltp/list/?series=476004&state=*

[1] https://lore.kernel.org/ltp/CAASaF6yjdrLLVnehESx1TjsrB_z48nmN_2i585GPfkG3Vvg15Q@mail.gmail.com/

Petr Vorel (4):
  shell: Add tst_sudo.c helper
  tst_test.sh: Add TST_USR_{G,U}ID variables
  ima_{conditionals,measurements}.sh: Use tst_sudo
  ima_conditionals.sh: Split test by request

 doc/users/setup_tests.rst                     |  4 +
 runtest/ima                                   |  5 +-
 .../integrity/ima/tests/ima_conditionals.sh   | 78 +++++++++++--------
 .../integrity/ima/tests/ima_measurements.sh   | 11 +--
 testcases/lib/.gitignore                      |  1 +
 testcases/lib/Makefile                        |  2 +-
 testcases/lib/tst_sudo.c                      | 51 ++++++++++++
 testcases/lib/tst_test.sh                     |  6 +-
 8 files changed, 115 insertions(+), 43 deletions(-)
 create mode 100644 testcases/lib/tst_sudo.c

-- 
2.51.0


^ permalink raw reply

* Re: [RFC v1 0/1] Implement IMA Event Log Trimming
From: Gregory Lumen @ 2025-11-26 23:40 UTC (permalink / raw)
  To: Roberto Sassu
  Cc: Anirudh Venkataramanan, linux-integrity, Mimi Zohar,
	Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Paul Moore,
	James Morris, Serge E . Hallyn, linux-security-module,
	Steven Chen, Lakshmi Ramasubramanian, Sush Shringarputale
In-Reply-To: <1e5a3b427fe2783e57e88ca14630f5e38e01fac5.camel@huaweicloud.com>

Greetings Roberto,

If I may chime in a bit:

> The only way to make the verification of measurements list snapshots
> work is that the verification state is stored outside the system to
> evaluate (which can be assumed to be trusted), so that you are sure
> that the system is not advancing the PCR starting value by itself.

You are correct; to make the described approach work, an external source 
of trust is required in order to detect unexpected or unauthorized 
trimming of the event log (for example, by signing the trim-to PCR values 
from the previous verification/attestation cycle). This should be true 
regardless of the mechanism of trimming. More generally, I will go so far 
as to suggest that any attempt to attest the integrity of a system using 
IMA will likely fall into one of two general approaches: either the entire 
IMA event log is retained (either in kernel or user space) from boot and 
claims of system integrity are built by validating and examining the 
entire log for signs of tampering, or an external source of trust is 
introduced to allow incremental validation and examination of the log. 
Other more innovative approaches may exist, but we make no such claims.

I will also say that it should be possible to implement either approach to 
attestation (retaining the entire log, or relying on an external source of 
trust) with any sane implementation for IMA log trimming.

As for our proposed implementation, storing the starting PCR values in the 
kernel preserving the ability for any arbitrary user space entity to 
validate the retained portion of the IMA event log against the TPM PCRs at 
any time, without requiring awareness of other user space mechanisms 
implemented by other entities that may be initiating IMA trimming 
operations. My personal sense is that this capability is worth preserving, 
but it is entirely possible the general consensus is that the value 
offered does not balance against the additional technical complexity when 
compared to simpler alternatives (discussed in a moment). To stress the 
point, this capability would only enable validation of the integrity of 
the retained portion of the event log and its continuity with the PCRs, 
and could not be used to make any claims as to the overall integrity of 
the system since, as you observed, an attacker who has successfully 
compromised the system could simply trim the event log in order to discard 
evidence of the compromise.

If the ability to validate the retained portion of the IMA event log is 
not worth designing for, we could instead go with a simpler "Trim-to-N" 
approach, where the user space interface allows for the specification of 
an absolute index into the IMA log to be used as the trim position (as 
opposed to using calculated PCR values to indicate trim position in our 
current proposal). To protect against unexpected behavior in the event of 
concurrent trims, index counting would need to be fixed (hence absolute) 
such that index 0 would always refer to the very first entry written 
during boot, even if that entry has already been trimmed, with the number 
of trimmed entries (and thus starting index of the retained log) exposed 
to use space via a pseudo-file.

With such a trim approach, it should be possible to implement either 
general attestation approach: retaining the entire log (copy the log to 
user space, then trim the copied entries), or relying on an external 
source of trust (quote, determine the log index corresponding to the quote 
plus PCRs, trim, then securely store the trim position/starting PCRs for 
future cycles).

-Gregory Lumen


^ permalink raw reply

* Re: [PATCHv2 1/2] kernel/kexec: Change the prototype of kimage_map_segment()
From: Pingfan Liu @ 2025-11-26  4:47 UTC (permalink / raw)
  To: Baoquan He
  Cc: kexec, linux-integrity, Andrew Morton, Mimi Zohar, Roberto Sassu,
	Alexander Graf, Steven Chen, stable
In-Reply-To: <aSZTb1X26MjSZIzF@MiWiFi-R3L-srv>

On Wed, Nov 26, 2025 at 9:10 AM Baoquan He <bhe@redhat.com> wrote:
>
> Hi Pingfan,
>
> On 11/06/25 at 02:59pm, Pingfan Liu wrote:
> > The kexec segment index will be required to extract the corresponding
> > information for that segment in kimage_map_segment(). Additionally,
> > kexec_segment already holds the kexec relocation destination address and
> > size. Therefore, the prototype of kimage_map_segment() can be changed.
>
> Because no cover letter, I just reply here.
>
> I am testing code of (tag: next-20251125, next/master) on arm64 system.
> I saw your two patches are already in there. When I used kexec reboot
> as below, I still got the warning message during ima_kexec_post_load()
> invocation.
>
> ====================
> kexec -d -l /boot/vmlinuz-6.18.0-rc7-next-20251125 --initrd /boot/initramfs-6.18.0-rc7-next-20251125.img --reuse-cmdline
> ====================
>

Could you share more detail, as I cannot reproduce this issue with
(tag: next-20251125, next/master) on a different aarch64 platform
either.
I use the default config to compile the kernel and add CMA=512M in the
kernel command line, so the kexec file load can allocate the dest
memory directly on the CMA area.

# lshw -class system
hpe-apollo***
    description: System
    product: CS500 (-)
    vendor: CRAY
    version: -
    serial: -
    width: 64 bits
    capabilities: smbios-3.1.1 dmi-3.1.1 smp sve_default_vector_length
tagged_addr_disabled
    configuration: boot=normal chassis=server family=HPC sku=-
uuid=8cdb9098-d03f-11e9-8001-2cd444ce8cad

#cat /proc/meminfo | grep -i cma
CmaTotal:         524288 kB
CmaFree:          509856 kB
# cd /boot/
# kexec -d -s -l vmlinuz-6.18.0-rc7-next-20251125 --initrd
initramfs-6.18.0-rc7-next-20251125.img --reuse-cmdline
arch_process_options:179: command_line:
root=/dev/mapper/rhel_hpe--apollo80--02--n00-root ro
earlycon=pl011,0x1c050000 ip=dhcp
crashkernel=2G-4G:406M,4G-64G:470M,64G-:726M
rd.lvm.lv=rhel_hpe-apollo80-02-n00/root
rd.lvm.lv=rhel_hpe-apollo80-02-n00/swap console=ttyAMA0  cma=512M
arch_process_options:181: initrd: initramfs-6.18.0-rc7-next-20251125.img
arch_process_options:183: dtb: (null)
arch_process_options:186: console: (null)
Try gzip decompression.
Try LZMA decompression.
elf_arm64_probe: Not an ELF executable.
image_arm64_probe: Bad arm64 image header.
pez_arm64_probe: PROBE.
Try gzip decompression.
pez_prepare: decompressed size 50790400
pez_prepare: done
# cat /proc/meminfo | grep -i cma
CmaTotal:         524288 kB
CmaFree:          411032 kB

CmaFree shrinks, which means the kexec_file_load uses it.

And the dmesg shows no warning
[  167.484064] kexec_file: kernel: 0000000096e14552 kernel_size: 0x3070000
[  167.484094] PEFILE: Unsigned PE binary
[  167.576003] ima: kexec measurement buffer for the loaded kernel at
0xc1a18000.
[  167.585054] kexec_file: Loaded initrd at 0xc4b70000 bufsz=0x300f306
memsz=0x3010000
[  167.593376] kexec_file: Loaded dtb at 0xc7c00000 bufsz=0x5b1 memsz=0x1000
[  167.593389] kexec_file(Image): Loaded kernel at 0xc1b00000
bufsz=0x3070000 memsz=0x3070000
[  167.593405] kexec_file: nr_segments = 4
[  167.593408] kexec_file: segment[0]: buf=0x0000000000000000
bufsz=0x0 mem=0xc1a18000 memsz=0x1000
[  167.593417] kexec_file: segment[1]: buf=0x0000000096e14552
bufsz=0x3070000 mem=0xc1b00000 memsz=0x3070000
[  167.610450] kexec_file: segment[2]: buf=0x000000001285672d
bufsz=0x300f306 mem=0xc4b70000 memsz=0x3010000
[  167.627563] kexec_file: segment[3]: buf=0x000000002ef3060d
bufsz=0x5b1 mem=0xc7c00000 memsz=0x1000
[  167.629228] machine_kexec_post_load:119:
[  167.629233]   kexec kimage info:
[  167.629236]     type:        0
[  167.629238]     head:        4
[  167.629241]     kern_reloc: 0x0000000000000000
[  167.629245]     el2_vectors: 0x0000000000000000
[  167.629248] kexec_file: kexec_file_load: type:0, start:0xc1b00000
head:0x4 flags:0x8


Thanks,

Pingfan


> ====================
> [34283.657670] kexec_file: kernel: 000000006cf71829 kernel_size: 0x48b0000
> [34283.657700] PEFILE: Unsigned PE binary
> [34283.676597] ima: kexec measurement buffer for the loaded kernel at 0xff206000.
> [34283.676621] kexec_file: Loaded initrd at 0x84cb0000 bufsz=0x25ec426 memsz=0x25ed000
> [34283.684646] kexec_file: Loaded dtb at 0xff400000 bufsz=0x39e memsz=0x1000
> [34283.684653] kexec_file(Image): Loaded kernel at 0x80400000 bufsz=0x48b0000 memsz=0x48b0000
> [34283.684663] kexec_file: nr_segments = 4
> [34283.684666] kexec_file: segment[0]: buf=0x0000000000000000 bufsz=0x0 mem=0xff206000 memsz=0x1000
> [34283.684674] kexec_file: segment[1]: buf=0x000000006cf71829 bufsz=0x48b0000 mem=0x80400000 memsz=0x48b0000
> [34283.725987] kexec_file: segment[2]: buf=0x00000000c7369de6 bufsz=0x25ec426 mem=0x84cb0000 memsz=0x25ed000
> [34283.747670] kexec_file: segmen
> ** replaying previous printk message **
> [34283.747670] kexec_file: segment[3]: buf=0x00000000d83b530b bufsz=0x39e mem=0xff400000 memsz=0x1000
> [34283.747973] ------------[ cut here ]------------
> [34283.747976] WARNING: CPU: 33 PID: 16112 at kernel/kexec_core.c:1002 kimage_map_segment+0x138/0x190
> [34283.778574] Modules linked in: rfkill vfat fat ipmi_ssif igb acpi_ipmi ipmi_si ipmi_devintf mlx5_fwctl i2c_algo_bit ipmi_msghandler fwctl fuse loop nfnetlink zram lz4hc_compress lz4_compress xfs mlx5_ib macsec mlx5_core nvme nvme_core mlxfw psample tls nvme_keyring nvme_auth pci_hyperv_intf sbsa_gwdt rpcrdma sunrpc rdma_ucm ib_uverbs ib_srpt ib_isert iscsi_target_mod target_core_mod ib_iser i2c_dev ib_umad rdma_cm ib_ipoib iw_cm ib_cm libiscsi ib_core scsi_transport_iscsi aes_neon_bs
> [34283.824233] CPU: 33 UID: 0 PID: 16112 Comm: kexec Tainted: G        W           6.17.8-200.fc42.aarch64 #1 PREEMPT(voluntary)
> [34283.836355] Tainted: [W]=WARN
> [34283.839684] Hardware name: CRAY CS500/CMUD        , BIOS 1.4.0 Jun 17 2020
> [34283.846903] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [34283.854243] pc : kimage_map_segment+0x138/0x190
> [34283.859120] lr : kimage_map_segment+0x4c/0x190
> [34283.863920] sp : ffff8000a0643a90
> [34283.867394] x29: ffff8000a0643a90 x28: ffff800083d0a000 x27: 0000000000000000
> [34283.874901] x26: 0000aaaad722d4b0 x25: 000000000000008f x24: ffff800083d0a000
> [34283.882608] x23: 0000000000000001 x22: 00000000ff206000 x21: 00000000ff207000
> [34283.890305] x20: ffff008fbd306980 x19: ffff008f895d6400 x18: 00000000fffffff9
> [34283.897815] x17: 303d6d656d206539 x16: 3378303d7a736675 x15: 646565732d676e72
> [34283.905516] x14: 00646565732d726c x13: 616d692c78756e69 x12: 6c00636578656b2d
> [34283.912999] x11: 007265666675622d x10: 636578656b2d616d x9 : ffff80008050b73c
> [34283.920691] x8 : 0001000000000000 x7 : 0000000000000000 x6 : 0000000080000000
> [34283.928197] x5 : 0000000084cb0000 x4 : ffff008fbd2306b0 x3 : ffff008fbd305000
> [34283.935898] x2 : fffffff7ff000000 x1 : 0000000000000004 x0 : ffff800082046000
> [34283.943603] Call trace:
> [34283.946039]  kimage_map_segment+0x138/0x190 (P)
> [34283.950935]  ima_kexec_post_load+0x58/0xc0
> [34283.955225]  __do_sys_kexec_file_load+0x2b8/0x398
> [34283.960279]  __arm64_sys_kexec_file_load+0x28/0x40
> [34283.965965]  invoke_syscall.constprop.0+0x64/0xe8
> [34283.971025]  el0_svc_common.constprop.0+0x40/0xe8
> [34283.975883]  do_el0_svc+0x24/0x38
> [34283.979361]  el0_svc+0x3c/0x168
> [34283.982833]  el0t_64_sync_handler+0xa0/0xf0
> [34283.987176]  el0t_64_sync+0x1b0/0x1b8
> [34283.991000] ---[ end trace 0000000000000000 ]---
> [34283.996060] ------------[ cut here ]------------
> [34283.996064] WARNING: CPU: 33 PID: 16112 at mm/vmalloc.c:538 vmap_pages_pte_range+0x2bc/0x3c0
> [34284.010006] Modules linked in: rfkill vfat fat ipmi_ssif igb acpi_ipmi ipmi_si ipmi_devintf mlx5_fwctl i2c_algo_bit ipmi_msghandler fwctl fuse loop nfnetlink zram lz4hc_compress lz4_compress xfs mlx5_ib macsec mlx5_core nvme nvme_core mlxfw psample tls nvme_keyring nvme_auth pci_hyperv_intf sbsa_gwdt rpcrdma sunrpc rdma_ucm ib_uverbs ib_srpt ib_isert iscsi_target_mod target_core_mod ib_iser i2c_dev ib_umad rdma_cm ib_ipoib iw_cm ib_cm libiscsi ib_core scsi_transport_iscsi aes_neon_bs
> [34284.055630] CPU: 33 UID: 0 PID: 16112 Comm: kexec Tainted: G        W           6.17.8-200.fc42.aarch64 #1 PREEMPT(voluntary)
> [34284.067701] Tainted: [W]=WARN
> [34284.070833] Hardware name: CRAY CS500/CMUD        , BIOS 1.4.0 Jun 17 2020
> [34284.078238] pstate: 40400009 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [34284.085546] pc : vmap_pages_pte_range+0x2bc/0x3c0
> [34284.090607] lr : vmap_small_pages_range_noflush+0x16c/0x298
> [34284.096528] sp : ffff8000a0643940
> [34284.100001] x29: ffff8000a0643940 x28: 0000000000000000 x27: ffff800084f76000
> [34284.107699] x26: fffffdffc0000000 x25: ffff8000a06439d0 x24: ffff800082046000
> [34284.115174] x23: ffff800084f75000 x22: ffff007f80337ba8 x21: 03ffffffffffffc0
> [34284.122821] x20: ffff008fbd306980 x19: ffff8000a06439d4 x18: 00000000fffffff9
> [34284.130331] x17: 303d6d656d206539 x16: 3378303d7a736675 x15: 646565732d676e72
> [34284.138032] x14: 0000000000004000 x13: ffff009781307130 x12: 0000000000002000
> [34284.145733] x11: 0000000000000000 x10: 0000000000000001 x9 : ffff8000804e197c
> [34284.153248] x8 : 0000000000000027 x7 : ffff800085175000 x6 : ffff8000a06439d4
> [34284.160944] x5 : ffff8000a06439d0 x4 : ffff008fbd306980 x3 : 0068000000000f03
> [34284.168449] x2 : ffff007f80337ba8 x1 : 0000000000000000 x0 : 0000000000000000
> [34284.176150] Call trace:
> [34284.178768]  vmap_pages_pte_range+0x2bc/0x3c0 (P)
> [34284.183665]  vmap_small_pages_range_noflush+0x16c/0x298
> [34284.189264]  vmap+0xb4/0x138
> [34284.192312]  kimage_map_segment+0xdc/0x190
> [34284.196794]  ima_kexec_post_load+0x58/0xc0
> [34284.201044]  __do_sys_kexec_file_load+0x2b8/0x398
> [34284.206107]  __arm64_sys_kexec_file_load+0x28/0x40
> [34284.211254]  invoke_syscall.constprop.0+0x64/0xe8
> [34284.216139]  el0_svc_common.constprop.0+0x40/0xe8
> [34284.221196]  do_el0_svc+0x24/0x38
> [34284.224678]  el0_svc+0x3c/0x168
> [34284.227983]  el0t_64_sync_handler+0xa0/0xf0
> [34284.232526]  el0t_64_sync+0x1b0/0x1b8
> [34284.236376] ---[ end trace 0000000000000000 ]---
> [34284.241412] kexec_core: Could not map ima buffer.
> [34284.241421] ima: Could not map measurements buffer.
> [34284.551336] machine_kexec_post_load:155:
> [34284.551354]   kexec kimage info:
> [34284.551366]     type:        0
> [34284.551373]     head:        90363f9002
> [34284.551377]     kern_reloc: 0x00000090363f7000
> [34284.551381]     el2_vectors: 0x0000000000000000
> [34284.551384] kexec_file: kexec_file_load: type:0, start:0x80400000 head:0x90363f9002 flags:0x8
> ====================
>
> >
> > Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
> > Signed-off-by: Pingfan Liu <piliu@redhat.com>
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Baoquan He <bhe@redhat.com>
> > Cc: Mimi Zohar <zohar@linux.ibm.com>
> > Cc: Roberto Sassu <roberto.sassu@huawei.com>
> > Cc: Alexander Graf <graf@amazon.com>
> > Cc: Steven Chen <chenste@linux.microsoft.com>
> > Cc: <stable@vger.kernel.org>
> > To: kexec@lists.infradead.org
> > To: linux-integrity@vger.kernel.org
> > ---
> >  include/linux/kexec.h              | 4 ++--
> >  kernel/kexec_core.c                | 9 ++++++---
> >  security/integrity/ima/ima_kexec.c | 4 +---
> >  3 files changed, 9 insertions(+), 8 deletions(-)
> >
> > diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> > index ff7e231b0485..8a22bc9b8c6c 100644
> > --- a/include/linux/kexec.h
> > +++ b/include/linux/kexec.h
> > @@ -530,7 +530,7 @@ extern bool kexec_file_dbg_print;
> >  #define kexec_dprintk(fmt, arg...) \
> >          do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0)
> >
> > -extern void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size);
> > +extern void *kimage_map_segment(struct kimage *image, int idx);
> >  extern void kimage_unmap_segment(void *buffer);
> >  #else /* !CONFIG_KEXEC_CORE */
> >  struct pt_regs;
> > @@ -540,7 +540,7 @@ static inline void __crash_kexec(struct pt_regs *regs) { }
> >  static inline void crash_kexec(struct pt_regs *regs) { }
> >  static inline int kexec_should_crash(struct task_struct *p) { return 0; }
> >  static inline int kexec_crash_loaded(void) { return 0; }
> > -static inline void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size)
> > +static inline void *kimage_map_segment(struct kimage *image, int idx)
> >  { return NULL; }
> >  static inline void kimage_unmap_segment(void *buffer) { }
> >  #define kexec_in_progress false
> > diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> > index fa00b239c5d9..9a1966207041 100644
> > --- a/kernel/kexec_core.c
> > +++ b/kernel/kexec_core.c
> > @@ -960,17 +960,20 @@ int kimage_load_segment(struct kimage *image, int idx)
> >       return result;
> >  }
> >
> > -void *kimage_map_segment(struct kimage *image,
> > -                      unsigned long addr, unsigned long size)
> > +void *kimage_map_segment(struct kimage *image, int idx)
> >  {
> > +     unsigned long addr, size, eaddr;
> >       unsigned long src_page_addr, dest_page_addr = 0;
> > -     unsigned long eaddr = addr + size;
> >       kimage_entry_t *ptr, entry;
> >       struct page **src_pages;
> >       unsigned int npages;
> >       void *vaddr = NULL;
> >       int i;
> >
> > +     addr = image->segment[idx].mem;
> > +     size = image->segment[idx].memsz;
> > +     eaddr = addr + size;
> > +
> >       /*
> >        * Collect the source pages and map them in a contiguous VA range.
> >        */
> > diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> > index 7362f68f2d8b..5beb69edd12f 100644
> > --- a/security/integrity/ima/ima_kexec.c
> > +++ b/security/integrity/ima/ima_kexec.c
> > @@ -250,9 +250,7 @@ void ima_kexec_post_load(struct kimage *image)
> >       if (!image->ima_buffer_addr)
> >               return;
> >
> > -     ima_kexec_buffer = kimage_map_segment(image,
> > -                                           image->ima_buffer_addr,
> > -                                           image->ima_buffer_size);
> > +     ima_kexec_buffer = kimage_map_segment(image, image->ima_segment_index);
> >       if (!ima_kexec_buffer) {
> >               pr_err("Could not map measurements buffer.\n");
> >               return;
> > --
> > 2.49.0
> >
>


^ permalink raw reply

* Re: [PATCHv2 1/2] kernel/kexec: Change the prototype of kimage_map_segment()
From: Pingfan Liu @ 2025-11-26  2:30 UTC (permalink / raw)
  To: Baoquan He
  Cc: Alexander Graf, makb, kexec, linux-integrity, Andrew Morton,
	Mimi Zohar, Roberto Sassu, Steven Chen, stable
In-Reply-To: <aSZdsNujdXiVr8HU@MiWiFi-R3L-srv>

On Wed, Nov 26, 2025 at 9:54 AM Baoquan He <bhe@redhat.com> wrote:
>
> Hi,
>
> On 11/26/25 at 09:10am, Baoquan He wrote:
> > Hi Pingfan,
> >
> > On 11/06/25 at 02:59pm, Pingfan Liu wrote:
> > > The kexec segment index will be required to extract the corresponding
> > > information for that segment in kimage_map_segment(). Additionally,
> > > kexec_segment already holds the kexec relocation destination address and
> > > size. Therefore, the prototype of kimage_map_segment() can be changed.
> >
> > Because no cover letter, I just reply here.
> >
> > I am testing code of (tag: next-20251125, next/master) on arm64 system.
> > I saw your two patches are already in there. When I used kexec reboot
> > as below, I still got the warning message during ima_kexec_post_load()
> > invocation.
>

I ran into this warning on the platform "NVIDIA Jetson Orin Nano". I
just got the control of this machine and have an opportunity to decode
its dtb.

I think the following section is critical to reproduce this issue

        reserved-memory {
                #address-cells = <0x02>;
                #size-cells = <0x02>;
                ranges;

                linux,cma {
                        linux,cma-default;
                        alignment = <0x00 0x10000>;
                        compatible = "shared-dma-pool";
                        size = <0x00 0x10000000>;
                        status = "okay";
                        reusable;
                };

That is weird. I used (tag: next-20251125, next/master) to have a
test, and  cann't see the warning any longer.

Once you finish with the machine, I'll run some tests to check if the
warning comes from the same root cause on your machine.

> And when I try to turn off cma allocating for kexec buffer, I found
> there's no such flag in user space utility kexec-tools. Since Alexander
> introduced commit 07d24902977e ("kexec: enable CMA based contiguous
> allocation"), but haven't add flag KEXEC_FILE_NO_CMA to kexec-tools, and
> Pingfan you are working to fix the bug, can any of you post patch to
> kexec-tools to add the flag?
>

OK.

> And flag KEXEC_FILE_FORCE_DTB too, which was introduced in commit f367474b5884
> ("x86/kexec: carry forward the boot DTB on kexec").
>

I have no idea about KEXEC_FILE_FORCE_DTB for the time being. But I
will see how to handle it properer.

Thanks,

Pingfan

> We only have them in kernel, but there's no chance to specify them,
> what's the meaning to have them?
>
> Thanks
> Baoquan
>
> >
> > ====================
> > kexec -d -l /boot/vmlinuz-6.18.0-rc7-next-20251125 --initrd /boot/initramfs-6.18.0-rc7-next-20251125.img --reuse-cmdline
> > ====================
> >
> > ====================
> > [34283.657670] kexec_file: kernel: 000000006cf71829 kernel_size: 0x48b0000
> > [34283.657700] PEFILE: Unsigned PE binary
> > [34283.676597] ima: kexec measurement buffer for the loaded kernel at 0xff206000.
> > [34283.676621] kexec_file: Loaded initrd at 0x84cb0000 bufsz=0x25ec426 memsz=0x25ed000
> > [34283.684646] kexec_file: Loaded dtb at 0xff400000 bufsz=0x39e memsz=0x1000
> > [34283.684653] kexec_file(Image): Loaded kernel at 0x80400000 bufsz=0x48b0000 memsz=0x48b0000
> > [34283.684663] kexec_file: nr_segments = 4
> > [34283.684666] kexec_file: segment[0]: buf=0x0000000000000000 bufsz=0x0 mem=0xff206000 memsz=0x1000
> > [34283.684674] kexec_file: segment[1]: buf=0x000000006cf71829 bufsz=0x48b0000 mem=0x80400000 memsz=0x48b0000
> > [34283.725987] kexec_file: segment[2]: buf=0x00000000c7369de6 bufsz=0x25ec426 mem=0x84cb0000 memsz=0x25ed000
> > [34283.747670] kexec_file: segmen
> > ** replaying previous printk message **
> > [34283.747670] kexec_file: segment[3]: buf=0x00000000d83b530b bufsz=0x39e mem=0xff400000 memsz=0x1000
> > [34283.747973] ------------[ cut here ]------------
> > [34283.747976] WARNING: CPU: 33 PID: 16112 at kernel/kexec_core.c:1002 kimage_map_segment+0x138/0x190
> > [34283.778574] Modules linked in: rfkill vfat fat ipmi_ssif igb acpi_ipmi ipmi_si ipmi_devintf mlx5_fwctl i2c_algo_bit ipmi_msghandler fwctl fuse loop nfnetlink zram lz4hc_compress lz4_compress xfs mlx5_ib macsec mlx5_core nvme nvme_core mlxfw psample tls nvme_keyring nvme_auth pci_hyperv_intf sbsa_gwdt rpcrdma sunrpc rdma_ucm ib_uverbs ib_srpt ib_isert iscsi_target_mod target_core_mod ib_iser i2c_dev ib_umad rdma_cm ib_ipoib iw_cm ib_cm libiscsi ib_core scsi_transport_iscsi aes_neon_bs
> > [34283.824233] CPU: 33 UID: 0 PID: 16112 Comm: kexec Tainted: G        W           6.17.8-200.fc42.aarch64 #1 PREEMPT(voluntary)
> > [34283.836355] Tainted: [W]=WARN
> > [34283.839684] Hardware name: CRAY CS500/CMUD        , BIOS 1.4.0 Jun 17 2020
> > [34283.846903] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > [34283.854243] pc : kimage_map_segment+0x138/0x190
> > [34283.859120] lr : kimage_map_segment+0x4c/0x190
> > [34283.863920] sp : ffff8000a0643a90
> > [34283.867394] x29: ffff8000a0643a90 x28: ffff800083d0a000 x27: 0000000000000000
> > [34283.874901] x26: 0000aaaad722d4b0 x25: 000000000000008f x24: ffff800083d0a000
> > [34283.882608] x23: 0000000000000001 x22: 00000000ff206000 x21: 00000000ff207000
> > [34283.890305] x20: ffff008fbd306980 x19: ffff008f895d6400 x18: 00000000fffffff9
> > [34283.897815] x17: 303d6d656d206539 x16: 3378303d7a736675 x15: 646565732d676e72
> > [34283.905516] x14: 00646565732d726c x13: 616d692c78756e69 x12: 6c00636578656b2d
> > [34283.912999] x11: 007265666675622d x10: 636578656b2d616d x9 : ffff80008050b73c
> > [34283.920691] x8 : 0001000000000000 x7 : 0000000000000000 x6 : 0000000080000000
> > [34283.928197] x5 : 0000000084cb0000 x4 : ffff008fbd2306b0 x3 : ffff008fbd305000
> > [34283.935898] x2 : fffffff7ff000000 x1 : 0000000000000004 x0 : ffff800082046000
> > [34283.943603] Call trace:
> > [34283.946039]  kimage_map_segment+0x138/0x190 (P)
> > [34283.950935]  ima_kexec_post_load+0x58/0xc0
> > [34283.955225]  __do_sys_kexec_file_load+0x2b8/0x398
> > [34283.960279]  __arm64_sys_kexec_file_load+0x28/0x40
> > [34283.965965]  invoke_syscall.constprop.0+0x64/0xe8
> > [34283.971025]  el0_svc_common.constprop.0+0x40/0xe8
> > [34283.975883]  do_el0_svc+0x24/0x38
> > [34283.979361]  el0_svc+0x3c/0x168
> > [34283.982833]  el0t_64_sync_handler+0xa0/0xf0
> > [34283.987176]  el0t_64_sync+0x1b0/0x1b8
> > [34283.991000] ---[ end trace 0000000000000000 ]---
> > [34283.996060] ------------[ cut here ]------------
> > [34283.996064] WARNING: CPU: 33 PID: 16112 at mm/vmalloc.c:538 vmap_pages_pte_range+0x2bc/0x3c0
> > [34284.010006] Modules linked in: rfkill vfat fat ipmi_ssif igb acpi_ipmi ipmi_si ipmi_devintf mlx5_fwctl i2c_algo_bit ipmi_msghandler fwctl fuse loop nfnetlink zram lz4hc_compress lz4_compress xfs mlx5_ib macsec mlx5_core nvme nvme_core mlxfw psample tls nvme_keyring nvme_auth pci_hyperv_intf sbsa_gwdt rpcrdma sunrpc rdma_ucm ib_uverbs ib_srpt ib_isert iscsi_target_mod target_core_mod ib_iser i2c_dev ib_umad rdma_cm ib_ipoib iw_cm ib_cm libiscsi ib_core scsi_transport_iscsi aes_neon_bs
> > [34284.055630] CPU: 33 UID: 0 PID: 16112 Comm: kexec Tainted: G        W           6.17.8-200.fc42.aarch64 #1 PREEMPT(voluntary)
> > [34284.067701] Tainted: [W]=WARN
> > [34284.070833] Hardware name: CRAY CS500/CMUD        , BIOS 1.4.0 Jun 17 2020
> > [34284.078238] pstate: 40400009 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > [34284.085546] pc : vmap_pages_pte_range+0x2bc/0x3c0
> > [34284.090607] lr : vmap_small_pages_range_noflush+0x16c/0x298
> > [34284.096528] sp : ffff8000a0643940
> > [34284.100001] x29: ffff8000a0643940 x28: 0000000000000000 x27: ffff800084f76000
> > [34284.107699] x26: fffffdffc0000000 x25: ffff8000a06439d0 x24: ffff800082046000
> > [34284.115174] x23: ffff800084f75000 x22: ffff007f80337ba8 x21: 03ffffffffffffc0
> > [34284.122821] x20: ffff008fbd306980 x19: ffff8000a06439d4 x18: 00000000fffffff9
> > [34284.130331] x17: 303d6d656d206539 x16: 3378303d7a736675 x15: 646565732d676e72
> > [34284.138032] x14: 0000000000004000 x13: ffff009781307130 x12: 0000000000002000
> > [34284.145733] x11: 0000000000000000 x10: 0000000000000001 x9 : ffff8000804e197c
> > [34284.153248] x8 : 0000000000000027 x7 : ffff800085175000 x6 : ffff8000a06439d4
> > [34284.160944] x5 : ffff8000a06439d0 x4 : ffff008fbd306980 x3 : 0068000000000f03
> > [34284.168449] x2 : ffff007f80337ba8 x1 : 0000000000000000 x0 : 0000000000000000
> > [34284.176150] Call trace:
> > [34284.178768]  vmap_pages_pte_range+0x2bc/0x3c0 (P)
> > [34284.183665]  vmap_small_pages_range_noflush+0x16c/0x298
> > [34284.189264]  vmap+0xb4/0x138
> > [34284.192312]  kimage_map_segment+0xdc/0x190
> > [34284.196794]  ima_kexec_post_load+0x58/0xc0
> > [34284.201044]  __do_sys_kexec_file_load+0x2b8/0x398
> > [34284.206107]  __arm64_sys_kexec_file_load+0x28/0x40
> > [34284.211254]  invoke_syscall.constprop.0+0x64/0xe8
> > [34284.216139]  el0_svc_common.constprop.0+0x40/0xe8
> > [34284.221196]  do_el0_svc+0x24/0x38
> > [34284.224678]  el0_svc+0x3c/0x168
> > [34284.227983]  el0t_64_sync_handler+0xa0/0xf0
> > [34284.232526]  el0t_64_sync+0x1b0/0x1b8
> > [34284.236376] ---[ end trace 0000000000000000 ]---
> > [34284.241412] kexec_core: Could not map ima buffer.
> > [34284.241421] ima: Could not map measurements buffer.
> > [34284.551336] machine_kexec_post_load:155:
> > [34284.551354]   kexec kimage info:
> > [34284.551366]     type:        0
> > [34284.551373]     head:        90363f9002
> > [34284.551377]     kern_reloc: 0x00000090363f7000
> > [34284.551381]     el2_vectors: 0x0000000000000000
> > [34284.551384] kexec_file: kexec_file_load: type:0, start:0x80400000 head:0x90363f9002 flags:0x8
> > ====================
> >
> > >
> > > Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
> > > Signed-off-by: Pingfan Liu <piliu@redhat.com>
> > > Cc: Andrew Morton <akpm@linux-foundation.org>
> > > Cc: Baoquan He <bhe@redhat.com>
> > > Cc: Mimi Zohar <zohar@linux.ibm.com>
> > > Cc: Roberto Sassu <roberto.sassu@huawei.com>
> > > Cc: Alexander Graf <graf@amazon.com>
> > > Cc: Steven Chen <chenste@linux.microsoft.com>
> > > Cc: <stable@vger.kernel.org>
> > > To: kexec@lists.infradead.org
> > > To: linux-integrity@vger.kernel.org
> > > ---
> > >  include/linux/kexec.h              | 4 ++--
> > >  kernel/kexec_core.c                | 9 ++++++---
> > >  security/integrity/ima/ima_kexec.c | 4 +---
> > >  3 files changed, 9 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> > > index ff7e231b0485..8a22bc9b8c6c 100644
> > > --- a/include/linux/kexec.h
> > > +++ b/include/linux/kexec.h
> > > @@ -530,7 +530,7 @@ extern bool kexec_file_dbg_print;
> > >  #define kexec_dprintk(fmt, arg...) \
> > >          do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0)
> > >
> > > -extern void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size);
> > > +extern void *kimage_map_segment(struct kimage *image, int idx);
> > >  extern void kimage_unmap_segment(void *buffer);
> > >  #else /* !CONFIG_KEXEC_CORE */
> > >  struct pt_regs;
> > > @@ -540,7 +540,7 @@ static inline void __crash_kexec(struct pt_regs *regs) { }
> > >  static inline void crash_kexec(struct pt_regs *regs) { }
> > >  static inline int kexec_should_crash(struct task_struct *p) { return 0; }
> > >  static inline int kexec_crash_loaded(void) { return 0; }
> > > -static inline void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size)
> > > +static inline void *kimage_map_segment(struct kimage *image, int idx)
> > >  { return NULL; }
> > >  static inline void kimage_unmap_segment(void *buffer) { }
> > >  #define kexec_in_progress false
> > > diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> > > index fa00b239c5d9..9a1966207041 100644
> > > --- a/kernel/kexec_core.c
> > > +++ b/kernel/kexec_core.c
> > > @@ -960,17 +960,20 @@ int kimage_load_segment(struct kimage *image, int idx)
> > >     return result;
> > >  }
> > >
> > > -void *kimage_map_segment(struct kimage *image,
> > > -                    unsigned long addr, unsigned long size)
> > > +void *kimage_map_segment(struct kimage *image, int idx)
> > >  {
> > > +   unsigned long addr, size, eaddr;
> > >     unsigned long src_page_addr, dest_page_addr = 0;
> > > -   unsigned long eaddr = addr + size;
> > >     kimage_entry_t *ptr, entry;
> > >     struct page **src_pages;
> > >     unsigned int npages;
> > >     void *vaddr = NULL;
> > >     int i;
> > >
> > > +   addr = image->segment[idx].mem;
> > > +   size = image->segment[idx].memsz;
> > > +   eaddr = addr + size;
> > > +
> > >     /*
> > >      * Collect the source pages and map them in a contiguous VA range.
> > >      */
> > > diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> > > index 7362f68f2d8b..5beb69edd12f 100644
> > > --- a/security/integrity/ima/ima_kexec.c
> > > +++ b/security/integrity/ima/ima_kexec.c
> > > @@ -250,9 +250,7 @@ void ima_kexec_post_load(struct kimage *image)
> > >     if (!image->ima_buffer_addr)
> > >             return;
> > >
> > > -   ima_kexec_buffer = kimage_map_segment(image,
> > > -                                         image->ima_buffer_addr,
> > > -                                         image->ima_buffer_size);
> > > +   ima_kexec_buffer = kimage_map_segment(image, image->ima_segment_index);
> > >     if (!ima_kexec_buffer) {
> > >             pr_err("Could not map measurements buffer.\n");
> > >             return;
> > > --
> > > 2.49.0
> > >
> >
>


^ permalink raw reply

* Re: [PATCHv2 1/2] kernel/kexec: Change the prototype of kimage_map_segment()
From: Baoquan He @ 2025-11-26  1:53 UTC (permalink / raw)
  To: Pingfan Liu, Alexander Graf, makb
  Cc: kexec, linux-integrity, Andrew Morton, Mimi Zohar, Roberto Sassu,
	Steven Chen, stable
In-Reply-To: <aSZTb1X26MjSZIzF@MiWiFi-R3L-srv>

Hi,

On 11/26/25 at 09:10am, Baoquan He wrote:
> Hi Pingfan,
> 
> On 11/06/25 at 02:59pm, Pingfan Liu wrote:
> > The kexec segment index will be required to extract the corresponding
> > information for that segment in kimage_map_segment(). Additionally,
> > kexec_segment already holds the kexec relocation destination address and
> > size. Therefore, the prototype of kimage_map_segment() can be changed.
> 
> Because no cover letter, I just reply here.
> 
> I am testing code of (tag: next-20251125, next/master) on arm64 system.
> I saw your two patches are already in there. When I used kexec reboot
> as below, I still got the warning message during ima_kexec_post_load()
> invocation. 

And when I try to turn off cma allocating for kexec buffer, I found
there's no such flag in user space utility kexec-tools. Since Alexander
introduced commit 07d24902977e ("kexec: enable CMA based contiguous
allocation"), but haven't add flag KEXEC_FILE_NO_CMA to kexec-tools, and
Pingfan you are working to fix the bug, can any of you post patch to
kexec-tools to add the flag?

And flag KEXEC_FILE_FORCE_DTB too, which was introduced in commit f367474b5884
("x86/kexec: carry forward the boot DTB on kexec").

We only have them in kernel, but there's no chance to specify them,
what's the meaning to have them?

Thanks
Baoquan

> 
> ====================
> kexec -d -l /boot/vmlinuz-6.18.0-rc7-next-20251125 --initrd /boot/initramfs-6.18.0-rc7-next-20251125.img --reuse-cmdline
> ====================
> 
> ====================
> [34283.657670] kexec_file: kernel: 000000006cf71829 kernel_size: 0x48b0000
> [34283.657700] PEFILE: Unsigned PE binary
> [34283.676597] ima: kexec measurement buffer for the loaded kernel at 0xff206000.
> [34283.676621] kexec_file: Loaded initrd at 0x84cb0000 bufsz=0x25ec426 memsz=0x25ed000
> [34283.684646] kexec_file: Loaded dtb at 0xff400000 bufsz=0x39e memsz=0x1000
> [34283.684653] kexec_file(Image): Loaded kernel at 0x80400000 bufsz=0x48b0000 memsz=0x48b0000
> [34283.684663] kexec_file: nr_segments = 4
> [34283.684666] kexec_file: segment[0]: buf=0x0000000000000000 bufsz=0x0 mem=0xff206000 memsz=0x1000
> [34283.684674] kexec_file: segment[1]: buf=0x000000006cf71829 bufsz=0x48b0000 mem=0x80400000 memsz=0x48b0000
> [34283.725987] kexec_file: segment[2]: buf=0x00000000c7369de6 bufsz=0x25ec426 mem=0x84cb0000 memsz=0x25ed000
> [34283.747670] kexec_file: segmen
> ** replaying previous printk message **
> [34283.747670] kexec_file: segment[3]: buf=0x00000000d83b530b bufsz=0x39e mem=0xff400000 memsz=0x1000
> [34283.747973] ------------[ cut here ]------------
> [34283.747976] WARNING: CPU: 33 PID: 16112 at kernel/kexec_core.c:1002 kimage_map_segment+0x138/0x190
> [34283.778574] Modules linked in: rfkill vfat fat ipmi_ssif igb acpi_ipmi ipmi_si ipmi_devintf mlx5_fwctl i2c_algo_bit ipmi_msghandler fwctl fuse loop nfnetlink zram lz4hc_compress lz4_compress xfs mlx5_ib macsec mlx5_core nvme nvme_core mlxfw psample tls nvme_keyring nvme_auth pci_hyperv_intf sbsa_gwdt rpcrdma sunrpc rdma_ucm ib_uverbs ib_srpt ib_isert iscsi_target_mod target_core_mod ib_iser i2c_dev ib_umad rdma_cm ib_ipoib iw_cm ib_cm libiscsi ib_core scsi_transport_iscsi aes_neon_bs
> [34283.824233] CPU: 33 UID: 0 PID: 16112 Comm: kexec Tainted: G        W           6.17.8-200.fc42.aarch64 #1 PREEMPT(voluntary) 
> [34283.836355] Tainted: [W]=WARN
> [34283.839684] Hardware name: CRAY CS500/CMUD        , BIOS 1.4.0 Jun 17 2020
> [34283.846903] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [34283.854243] pc : kimage_map_segment+0x138/0x190
> [34283.859120] lr : kimage_map_segment+0x4c/0x190
> [34283.863920] sp : ffff8000a0643a90
> [34283.867394] x29: ffff8000a0643a90 x28: ffff800083d0a000 x27: 0000000000000000
> [34283.874901] x26: 0000aaaad722d4b0 x25: 000000000000008f x24: ffff800083d0a000
> [34283.882608] x23: 0000000000000001 x22: 00000000ff206000 x21: 00000000ff207000
> [34283.890305] x20: ffff008fbd306980 x19: ffff008f895d6400 x18: 00000000fffffff9
> [34283.897815] x17: 303d6d656d206539 x16: 3378303d7a736675 x15: 646565732d676e72
> [34283.905516] x14: 00646565732d726c x13: 616d692c78756e69 x12: 6c00636578656b2d
> [34283.912999] x11: 007265666675622d x10: 636578656b2d616d x9 : ffff80008050b73c
> [34283.920691] x8 : 0001000000000000 x7 : 0000000000000000 x6 : 0000000080000000
> [34283.928197] x5 : 0000000084cb0000 x4 : ffff008fbd2306b0 x3 : ffff008fbd305000
> [34283.935898] x2 : fffffff7ff000000 x1 : 0000000000000004 x0 : ffff800082046000
> [34283.943603] Call trace:
> [34283.946039]  kimage_map_segment+0x138/0x190 (P)
> [34283.950935]  ima_kexec_post_load+0x58/0xc0
> [34283.955225]  __do_sys_kexec_file_load+0x2b8/0x398
> [34283.960279]  __arm64_sys_kexec_file_load+0x28/0x40
> [34283.965965]  invoke_syscall.constprop.0+0x64/0xe8
> [34283.971025]  el0_svc_common.constprop.0+0x40/0xe8
> [34283.975883]  do_el0_svc+0x24/0x38
> [34283.979361]  el0_svc+0x3c/0x168
> [34283.982833]  el0t_64_sync_handler+0xa0/0xf0
> [34283.987176]  el0t_64_sync+0x1b0/0x1b8
> [34283.991000] ---[ end trace 0000000000000000 ]---
> [34283.996060] ------------[ cut here ]------------
> [34283.996064] WARNING: CPU: 33 PID: 16112 at mm/vmalloc.c:538 vmap_pages_pte_range+0x2bc/0x3c0
> [34284.010006] Modules linked in: rfkill vfat fat ipmi_ssif igb acpi_ipmi ipmi_si ipmi_devintf mlx5_fwctl i2c_algo_bit ipmi_msghandler fwctl fuse loop nfnetlink zram lz4hc_compress lz4_compress xfs mlx5_ib macsec mlx5_core nvme nvme_core mlxfw psample tls nvme_keyring nvme_auth pci_hyperv_intf sbsa_gwdt rpcrdma sunrpc rdma_ucm ib_uverbs ib_srpt ib_isert iscsi_target_mod target_core_mod ib_iser i2c_dev ib_umad rdma_cm ib_ipoib iw_cm ib_cm libiscsi ib_core scsi_transport_iscsi aes_neon_bs
> [34284.055630] CPU: 33 UID: 0 PID: 16112 Comm: kexec Tainted: G        W           6.17.8-200.fc42.aarch64 #1 PREEMPT(voluntary) 
> [34284.067701] Tainted: [W]=WARN
> [34284.070833] Hardware name: CRAY CS500/CMUD        , BIOS 1.4.0 Jun 17 2020
> [34284.078238] pstate: 40400009 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [34284.085546] pc : vmap_pages_pte_range+0x2bc/0x3c0
> [34284.090607] lr : vmap_small_pages_range_noflush+0x16c/0x298
> [34284.096528] sp : ffff8000a0643940
> [34284.100001] x29: ffff8000a0643940 x28: 0000000000000000 x27: ffff800084f76000
> [34284.107699] x26: fffffdffc0000000 x25: ffff8000a06439d0 x24: ffff800082046000
> [34284.115174] x23: ffff800084f75000 x22: ffff007f80337ba8 x21: 03ffffffffffffc0
> [34284.122821] x20: ffff008fbd306980 x19: ffff8000a06439d4 x18: 00000000fffffff9
> [34284.130331] x17: 303d6d656d206539 x16: 3378303d7a736675 x15: 646565732d676e72
> [34284.138032] x14: 0000000000004000 x13: ffff009781307130 x12: 0000000000002000
> [34284.145733] x11: 0000000000000000 x10: 0000000000000001 x9 : ffff8000804e197c
> [34284.153248] x8 : 0000000000000027 x7 : ffff800085175000 x6 : ffff8000a06439d4
> [34284.160944] x5 : ffff8000a06439d0 x4 : ffff008fbd306980 x3 : 0068000000000f03
> [34284.168449] x2 : ffff007f80337ba8 x1 : 0000000000000000 x0 : 0000000000000000
> [34284.176150] Call trace:
> [34284.178768]  vmap_pages_pte_range+0x2bc/0x3c0 (P)
> [34284.183665]  vmap_small_pages_range_noflush+0x16c/0x298
> [34284.189264]  vmap+0xb4/0x138
> [34284.192312]  kimage_map_segment+0xdc/0x190
> [34284.196794]  ima_kexec_post_load+0x58/0xc0
> [34284.201044]  __do_sys_kexec_file_load+0x2b8/0x398
> [34284.206107]  __arm64_sys_kexec_file_load+0x28/0x40
> [34284.211254]  invoke_syscall.constprop.0+0x64/0xe8
> [34284.216139]  el0_svc_common.constprop.0+0x40/0xe8
> [34284.221196]  do_el0_svc+0x24/0x38
> [34284.224678]  el0_svc+0x3c/0x168
> [34284.227983]  el0t_64_sync_handler+0xa0/0xf0
> [34284.232526]  el0t_64_sync+0x1b0/0x1b8
> [34284.236376] ---[ end trace 0000000000000000 ]---
> [34284.241412] kexec_core: Could not map ima buffer.
> [34284.241421] ima: Could not map measurements buffer.
> [34284.551336] machine_kexec_post_load:155:
> [34284.551354]   kexec kimage info:
> [34284.551366]     type:        0
> [34284.551373]     head:        90363f9002
> [34284.551377]     kern_reloc: 0x00000090363f7000
> [34284.551381]     el2_vectors: 0x0000000000000000
> [34284.551384] kexec_file: kexec_file_load: type:0, start:0x80400000 head:0x90363f9002 flags:0x8
> ====================
> 
> > 
> > Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
> > Signed-off-by: Pingfan Liu <piliu@redhat.com>
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Baoquan He <bhe@redhat.com>
> > Cc: Mimi Zohar <zohar@linux.ibm.com>
> > Cc: Roberto Sassu <roberto.sassu@huawei.com>
> > Cc: Alexander Graf <graf@amazon.com>
> > Cc: Steven Chen <chenste@linux.microsoft.com>
> > Cc: <stable@vger.kernel.org>
> > To: kexec@lists.infradead.org
> > To: linux-integrity@vger.kernel.org
> > ---
> >  include/linux/kexec.h              | 4 ++--
> >  kernel/kexec_core.c                | 9 ++++++---
> >  security/integrity/ima/ima_kexec.c | 4 +---
> >  3 files changed, 9 insertions(+), 8 deletions(-)
> > 
> > diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> > index ff7e231b0485..8a22bc9b8c6c 100644
> > --- a/include/linux/kexec.h
> > +++ b/include/linux/kexec.h
> > @@ -530,7 +530,7 @@ extern bool kexec_file_dbg_print;
> >  #define kexec_dprintk(fmt, arg...) \
> >          do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0)
> >  
> > -extern void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size);
> > +extern void *kimage_map_segment(struct kimage *image, int idx);
> >  extern void kimage_unmap_segment(void *buffer);
> >  #else /* !CONFIG_KEXEC_CORE */
> >  struct pt_regs;
> > @@ -540,7 +540,7 @@ static inline void __crash_kexec(struct pt_regs *regs) { }
> >  static inline void crash_kexec(struct pt_regs *regs) { }
> >  static inline int kexec_should_crash(struct task_struct *p) { return 0; }
> >  static inline int kexec_crash_loaded(void) { return 0; }
> > -static inline void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size)
> > +static inline void *kimage_map_segment(struct kimage *image, int idx)
> >  { return NULL; }
> >  static inline void kimage_unmap_segment(void *buffer) { }
> >  #define kexec_in_progress false
> > diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> > index fa00b239c5d9..9a1966207041 100644
> > --- a/kernel/kexec_core.c
> > +++ b/kernel/kexec_core.c
> > @@ -960,17 +960,20 @@ int kimage_load_segment(struct kimage *image, int idx)
> >  	return result;
> >  }
> >  
> > -void *kimage_map_segment(struct kimage *image,
> > -			 unsigned long addr, unsigned long size)
> > +void *kimage_map_segment(struct kimage *image, int idx)
> >  {
> > +	unsigned long addr, size, eaddr;
> >  	unsigned long src_page_addr, dest_page_addr = 0;
> > -	unsigned long eaddr = addr + size;
> >  	kimage_entry_t *ptr, entry;
> >  	struct page **src_pages;
> >  	unsigned int npages;
> >  	void *vaddr = NULL;
> >  	int i;
> >  
> > +	addr = image->segment[idx].mem;
> > +	size = image->segment[idx].memsz;
> > +	eaddr = addr + size;
> > +
> >  	/*
> >  	 * Collect the source pages and map them in a contiguous VA range.
> >  	 */
> > diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> > index 7362f68f2d8b..5beb69edd12f 100644
> > --- a/security/integrity/ima/ima_kexec.c
> > +++ b/security/integrity/ima/ima_kexec.c
> > @@ -250,9 +250,7 @@ void ima_kexec_post_load(struct kimage *image)
> >  	if (!image->ima_buffer_addr)
> >  		return;
> >  
> > -	ima_kexec_buffer = kimage_map_segment(image,
> > -					      image->ima_buffer_addr,
> > -					      image->ima_buffer_size);
> > +	ima_kexec_buffer = kimage_map_segment(image, image->ima_segment_index);
> >  	if (!ima_kexec_buffer) {
> >  		pr_err("Could not map measurements buffer.\n");
> >  		return;
> > -- 
> > 2.49.0
> > 
> 


^ permalink raw reply

* Re: [PATCHv2 1/2] kernel/kexec: Change the prototype of kimage_map_segment()
From: Baoquan He @ 2025-11-26  1:10 UTC (permalink / raw)
  To: Pingfan Liu
  Cc: kexec, linux-integrity, Andrew Morton, Mimi Zohar, Roberto Sassu,
	Alexander Graf, Steven Chen, stable
In-Reply-To: <20251106065904.10772-1-piliu@redhat.com>

Hi Pingfan,

On 11/06/25 at 02:59pm, Pingfan Liu wrote:
> The kexec segment index will be required to extract the corresponding
> information for that segment in kimage_map_segment(). Additionally,
> kexec_segment already holds the kexec relocation destination address and
> size. Therefore, the prototype of kimage_map_segment() can be changed.

Because no cover letter, I just reply here.

I am testing code of (tag: next-20251125, next/master) on arm64 system.
I saw your two patches are already in there. When I used kexec reboot
as below, I still got the warning message during ima_kexec_post_load()
invocation. 

====================
kexec -d -l /boot/vmlinuz-6.18.0-rc7-next-20251125 --initrd /boot/initramfs-6.18.0-rc7-next-20251125.img --reuse-cmdline
====================

====================
[34283.657670] kexec_file: kernel: 000000006cf71829 kernel_size: 0x48b0000
[34283.657700] PEFILE: Unsigned PE binary
[34283.676597] ima: kexec measurement buffer for the loaded kernel at 0xff206000.
[34283.676621] kexec_file: Loaded initrd at 0x84cb0000 bufsz=0x25ec426 memsz=0x25ed000
[34283.684646] kexec_file: Loaded dtb at 0xff400000 bufsz=0x39e memsz=0x1000
[34283.684653] kexec_file(Image): Loaded kernel at 0x80400000 bufsz=0x48b0000 memsz=0x48b0000
[34283.684663] kexec_file: nr_segments = 4
[34283.684666] kexec_file: segment[0]: buf=0x0000000000000000 bufsz=0x0 mem=0xff206000 memsz=0x1000
[34283.684674] kexec_file: segment[1]: buf=0x000000006cf71829 bufsz=0x48b0000 mem=0x80400000 memsz=0x48b0000
[34283.725987] kexec_file: segment[2]: buf=0x00000000c7369de6 bufsz=0x25ec426 mem=0x84cb0000 memsz=0x25ed000
[34283.747670] kexec_file: segmen
** replaying previous printk message **
[34283.747670] kexec_file: segment[3]: buf=0x00000000d83b530b bufsz=0x39e mem=0xff400000 memsz=0x1000
[34283.747973] ------------[ cut here ]------------
[34283.747976] WARNING: CPU: 33 PID: 16112 at kernel/kexec_core.c:1002 kimage_map_segment+0x138/0x190
[34283.778574] Modules linked in: rfkill vfat fat ipmi_ssif igb acpi_ipmi ipmi_si ipmi_devintf mlx5_fwctl i2c_algo_bit ipmi_msghandler fwctl fuse loop nfnetlink zram lz4hc_compress lz4_compress xfs mlx5_ib macsec mlx5_core nvme nvme_core mlxfw psample tls nvme_keyring nvme_auth pci_hyperv_intf sbsa_gwdt rpcrdma sunrpc rdma_ucm ib_uverbs ib_srpt ib_isert iscsi_target_mod target_core_mod ib_iser i2c_dev ib_umad rdma_cm ib_ipoib iw_cm ib_cm libiscsi ib_core scsi_transport_iscsi aes_neon_bs
[34283.824233] CPU: 33 UID: 0 PID: 16112 Comm: kexec Tainted: G        W           6.17.8-200.fc42.aarch64 #1 PREEMPT(voluntary) 
[34283.836355] Tainted: [W]=WARN
[34283.839684] Hardware name: CRAY CS500/CMUD        , BIOS 1.4.0 Jun 17 2020
[34283.846903] pstate: 80400009 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[34283.854243] pc : kimage_map_segment+0x138/0x190
[34283.859120] lr : kimage_map_segment+0x4c/0x190
[34283.863920] sp : ffff8000a0643a90
[34283.867394] x29: ffff8000a0643a90 x28: ffff800083d0a000 x27: 0000000000000000
[34283.874901] x26: 0000aaaad722d4b0 x25: 000000000000008f x24: ffff800083d0a000
[34283.882608] x23: 0000000000000001 x22: 00000000ff206000 x21: 00000000ff207000
[34283.890305] x20: ffff008fbd306980 x19: ffff008f895d6400 x18: 00000000fffffff9
[34283.897815] x17: 303d6d656d206539 x16: 3378303d7a736675 x15: 646565732d676e72
[34283.905516] x14: 00646565732d726c x13: 616d692c78756e69 x12: 6c00636578656b2d
[34283.912999] x11: 007265666675622d x10: 636578656b2d616d x9 : ffff80008050b73c
[34283.920691] x8 : 0001000000000000 x7 : 0000000000000000 x6 : 0000000080000000
[34283.928197] x5 : 0000000084cb0000 x4 : ffff008fbd2306b0 x3 : ffff008fbd305000
[34283.935898] x2 : fffffff7ff000000 x1 : 0000000000000004 x0 : ffff800082046000
[34283.943603] Call trace:
[34283.946039]  kimage_map_segment+0x138/0x190 (P)
[34283.950935]  ima_kexec_post_load+0x58/0xc0
[34283.955225]  __do_sys_kexec_file_load+0x2b8/0x398
[34283.960279]  __arm64_sys_kexec_file_load+0x28/0x40
[34283.965965]  invoke_syscall.constprop.0+0x64/0xe8
[34283.971025]  el0_svc_common.constprop.0+0x40/0xe8
[34283.975883]  do_el0_svc+0x24/0x38
[34283.979361]  el0_svc+0x3c/0x168
[34283.982833]  el0t_64_sync_handler+0xa0/0xf0
[34283.987176]  el0t_64_sync+0x1b0/0x1b8
[34283.991000] ---[ end trace 0000000000000000 ]---
[34283.996060] ------------[ cut here ]------------
[34283.996064] WARNING: CPU: 33 PID: 16112 at mm/vmalloc.c:538 vmap_pages_pte_range+0x2bc/0x3c0
[34284.010006] Modules linked in: rfkill vfat fat ipmi_ssif igb acpi_ipmi ipmi_si ipmi_devintf mlx5_fwctl i2c_algo_bit ipmi_msghandler fwctl fuse loop nfnetlink zram lz4hc_compress lz4_compress xfs mlx5_ib macsec mlx5_core nvme nvme_core mlxfw psample tls nvme_keyring nvme_auth pci_hyperv_intf sbsa_gwdt rpcrdma sunrpc rdma_ucm ib_uverbs ib_srpt ib_isert iscsi_target_mod target_core_mod ib_iser i2c_dev ib_umad rdma_cm ib_ipoib iw_cm ib_cm libiscsi ib_core scsi_transport_iscsi aes_neon_bs
[34284.055630] CPU: 33 UID: 0 PID: 16112 Comm: kexec Tainted: G        W           6.17.8-200.fc42.aarch64 #1 PREEMPT(voluntary) 
[34284.067701] Tainted: [W]=WARN
[34284.070833] Hardware name: CRAY CS500/CMUD        , BIOS 1.4.0 Jun 17 2020
[34284.078238] pstate: 40400009 (nZcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[34284.085546] pc : vmap_pages_pte_range+0x2bc/0x3c0
[34284.090607] lr : vmap_small_pages_range_noflush+0x16c/0x298
[34284.096528] sp : ffff8000a0643940
[34284.100001] x29: ffff8000a0643940 x28: 0000000000000000 x27: ffff800084f76000
[34284.107699] x26: fffffdffc0000000 x25: ffff8000a06439d0 x24: ffff800082046000
[34284.115174] x23: ffff800084f75000 x22: ffff007f80337ba8 x21: 03ffffffffffffc0
[34284.122821] x20: ffff008fbd306980 x19: ffff8000a06439d4 x18: 00000000fffffff9
[34284.130331] x17: 303d6d656d206539 x16: 3378303d7a736675 x15: 646565732d676e72
[34284.138032] x14: 0000000000004000 x13: ffff009781307130 x12: 0000000000002000
[34284.145733] x11: 0000000000000000 x10: 0000000000000001 x9 : ffff8000804e197c
[34284.153248] x8 : 0000000000000027 x7 : ffff800085175000 x6 : ffff8000a06439d4
[34284.160944] x5 : ffff8000a06439d0 x4 : ffff008fbd306980 x3 : 0068000000000f03
[34284.168449] x2 : ffff007f80337ba8 x1 : 0000000000000000 x0 : 0000000000000000
[34284.176150] Call trace:
[34284.178768]  vmap_pages_pte_range+0x2bc/0x3c0 (P)
[34284.183665]  vmap_small_pages_range_noflush+0x16c/0x298
[34284.189264]  vmap+0xb4/0x138
[34284.192312]  kimage_map_segment+0xdc/0x190
[34284.196794]  ima_kexec_post_load+0x58/0xc0
[34284.201044]  __do_sys_kexec_file_load+0x2b8/0x398
[34284.206107]  __arm64_sys_kexec_file_load+0x28/0x40
[34284.211254]  invoke_syscall.constprop.0+0x64/0xe8
[34284.216139]  el0_svc_common.constprop.0+0x40/0xe8
[34284.221196]  do_el0_svc+0x24/0x38
[34284.224678]  el0_svc+0x3c/0x168
[34284.227983]  el0t_64_sync_handler+0xa0/0xf0
[34284.232526]  el0t_64_sync+0x1b0/0x1b8
[34284.236376] ---[ end trace 0000000000000000 ]---
[34284.241412] kexec_core: Could not map ima buffer.
[34284.241421] ima: Could not map measurements buffer.
[34284.551336] machine_kexec_post_load:155:
[34284.551354]   kexec kimage info:
[34284.551366]     type:        0
[34284.551373]     head:        90363f9002
[34284.551377]     kern_reloc: 0x00000090363f7000
[34284.551381]     el2_vectors: 0x0000000000000000
[34284.551384] kexec_file: kexec_file_load: type:0, start:0x80400000 head:0x90363f9002 flags:0x8
====================

> 
> Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
> Signed-off-by: Pingfan Liu <piliu@redhat.com>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Baoquan He <bhe@redhat.com>
> Cc: Mimi Zohar <zohar@linux.ibm.com>
> Cc: Roberto Sassu <roberto.sassu@huawei.com>
> Cc: Alexander Graf <graf@amazon.com>
> Cc: Steven Chen <chenste@linux.microsoft.com>
> Cc: <stable@vger.kernel.org>
> To: kexec@lists.infradead.org
> To: linux-integrity@vger.kernel.org
> ---
>  include/linux/kexec.h              | 4 ++--
>  kernel/kexec_core.c                | 9 ++++++---
>  security/integrity/ima/ima_kexec.c | 4 +---
>  3 files changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> index ff7e231b0485..8a22bc9b8c6c 100644
> --- a/include/linux/kexec.h
> +++ b/include/linux/kexec.h
> @@ -530,7 +530,7 @@ extern bool kexec_file_dbg_print;
>  #define kexec_dprintk(fmt, arg...) \
>          do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0)
>  
> -extern void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size);
> +extern void *kimage_map_segment(struct kimage *image, int idx);
>  extern void kimage_unmap_segment(void *buffer);
>  #else /* !CONFIG_KEXEC_CORE */
>  struct pt_regs;
> @@ -540,7 +540,7 @@ static inline void __crash_kexec(struct pt_regs *regs) { }
>  static inline void crash_kexec(struct pt_regs *regs) { }
>  static inline int kexec_should_crash(struct task_struct *p) { return 0; }
>  static inline int kexec_crash_loaded(void) { return 0; }
> -static inline void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size)
> +static inline void *kimage_map_segment(struct kimage *image, int idx)
>  { return NULL; }
>  static inline void kimage_unmap_segment(void *buffer) { }
>  #define kexec_in_progress false
> diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> index fa00b239c5d9..9a1966207041 100644
> --- a/kernel/kexec_core.c
> +++ b/kernel/kexec_core.c
> @@ -960,17 +960,20 @@ int kimage_load_segment(struct kimage *image, int idx)
>  	return result;
>  }
>  
> -void *kimage_map_segment(struct kimage *image,
> -			 unsigned long addr, unsigned long size)
> +void *kimage_map_segment(struct kimage *image, int idx)
>  {
> +	unsigned long addr, size, eaddr;
>  	unsigned long src_page_addr, dest_page_addr = 0;
> -	unsigned long eaddr = addr + size;
>  	kimage_entry_t *ptr, entry;
>  	struct page **src_pages;
>  	unsigned int npages;
>  	void *vaddr = NULL;
>  	int i;
>  
> +	addr = image->segment[idx].mem;
> +	size = image->segment[idx].memsz;
> +	eaddr = addr + size;
> +
>  	/*
>  	 * Collect the source pages and map them in a contiguous VA range.
>  	 */
> diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> index 7362f68f2d8b..5beb69edd12f 100644
> --- a/security/integrity/ima/ima_kexec.c
> +++ b/security/integrity/ima/ima_kexec.c
> @@ -250,9 +250,7 @@ void ima_kexec_post_load(struct kimage *image)
>  	if (!image->ima_buffer_addr)
>  		return;
>  
> -	ima_kexec_buffer = kimage_map_segment(image,
> -					      image->ima_buffer_addr,
> -					      image->ima_buffer_size);
> +	ima_kexec_buffer = kimage_map_segment(image, image->ima_segment_index);
>  	if (!ima_kexec_buffer) {
>  		pr_err("Could not map measurements buffer.\n");
>  		return;
> -- 
> 2.49.0
> 


^ permalink raw reply

* Re: [PATCHv2 1/2] kernel/kexec: Change the prototype of kimage_map_segment()
From: Andrew Morton @ 2025-11-25 17:55 UTC (permalink / raw)
  To: Baoquan He
  Cc: Pingfan Liu, kexec, linux-integrity, Mimi Zohar, Roberto Sassu,
	Alexander Graf, Steven Chen, stable
In-Reply-To: <aSU2jy/ujJILHH9n@MiWiFi-R3L-srv>

On Tue, 25 Nov 2025 12:54:39 +0800 Baoquan He <bhe@redhat.com> wrote:

> On 11/24/25 at 02:16pm, Andrew Morton wrote:
> > On Thu,  6 Nov 2025 14:59:03 +0800 Pingfan Liu <piliu@redhat.com> wrote:
> > 
> > > The kexec segment index will be required to extract the corresponding
> > > information for that segment in kimage_map_segment(). Additionally,
> > > kexec_segment already holds the kexec relocation destination address and
> > > size. Therefore, the prototype of kimage_map_segment() can be changed.
> > 
> > Could we please have some reviewer input on thee two patches?
> 
> I have some concerns about the one place of tiny code change, and the
> root cause missing in log. And Mimi sent mail to me asking why this bug
> can'e be seen on her laptop, I told her this bug can only be triggered
> on system where CMA area exists. I think these need be addressed in v3.

Great, thanks, I'll drop this version.

^ permalink raw reply

* Re: [PATCH 1/1] tpm_crb: Fix a spelling mistake
From: Jarkko Sakkinen @ 2025-11-25 15:36 UTC (permalink / raw)
  To: Chu Guangqing; +Cc: peterhuewe, jgg, linux-integrity, linux-kernel
In-Reply-To: <20251125023030.3023-1-chuguangqing@inspur.com>

On Tue, Nov 25, 2025 at 10:30:30AM +0800, Chu Guangqing wrote:
> The spelling of the word "requrest" is incorrect; it should be "request".
> 
> Signed-off-by: Chu Guangqing <chuguangqing@inspur.com>
> ---
>  drivers/char/tpm/tpm_crb.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
> index c75a531cfb98..e094c517b96e 100644
> --- a/drivers/char/tpm/tpm_crb.c
> +++ b/drivers/char/tpm/tpm_crb.c
> @@ -412,7 +412,7 @@ static int crb_do_acpi_start(struct tpm_chip *chip)
>  #ifdef CONFIG_ARM64
>  /*
>   * This is a TPM Command Response Buffer start method that invokes a
> - * Secure Monitor Call to requrest the firmware to execute or cancel
> + * Secure Monitor Call to request the firmware to execute or cancel
>   * a TPM 2.0 command.
>   */
>  static int tpm_crb_smc_start(struct device *dev, unsigned long func_id)
> -- 
> 2.43.7
> 


Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>

BR, Jarkko

^ permalink raw reply

* Re: [PATCH] selftests: tpm2: Fix ill defined assertions
From: Jarkko Sakkinen @ 2025-11-25 15:36 UTC (permalink / raw)
  To: Maurice Hieronymus
  Cc: peterhuewe, linux-integrity, linux-kselftest, linux-kernel
In-Reply-To: <20251123111809.24634-1-mhi@mailbox.org>

On Sun, Nov 23, 2025 at 12:18:09PM +0100, Maurice Hieronymus wrote:
> Remove parentheses around assert statements in Python. With parentheses,
> assert always evaluates to True, making the checks ineffective.
> 
> Signed-off-by: Maurice Hieronymus <mhi@mailbox.org>
> ---
>  tools/testing/selftests/tpm2/tpm2.py | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/tpm2/tpm2.py b/tools/testing/selftests/tpm2/tpm2.py
> index bba8cb54548e..3d130c30bc7c 100644
> --- a/tools/testing/selftests/tpm2/tpm2.py
> +++ b/tools/testing/selftests/tpm2/tpm2.py
> @@ -437,7 +437,7 @@ class Client:
>  
>      def extend_pcr(self, i, dig, bank_alg = TPM2_ALG_SHA1):
>          ds = get_digest_size(bank_alg)
> -        assert(ds == len(dig))
> +        assert ds == len(dig)
>  
>          auth_cmd = AuthCommand()
>  
> @@ -589,7 +589,7 @@ class Client:
>      def seal(self, parent_key, data, auth_value, policy_dig,
>               name_alg = TPM2_ALG_SHA1):
>          ds = get_digest_size(name_alg)
> -        assert(not policy_dig or ds == len(policy_dig))
> +        assert not policy_dig or ds == len(policy_dig)
>  
>          attributes = 0
>          if not policy_dig:
> 
> base-commit: 821e6e2a328bb907d40f8d1141d8b6c079aa7340
> -- 
> 2.50.1
> 


Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>

BR, Jarkko

^ permalink raw reply

* Re: [RFC][PATCH] exec: Move cred computation under exec_update_lock
From: Roberto Sassu @ 2025-11-25 11:55 UTC (permalink / raw)
  To: Eric W. Biederman, Bernd Edlinger
  Cc: Alexander Viro, Alexey Dobriyan, Oleg Nesterov, Kees Cook,
	Andy Lutomirski, Will Drewry, Christian Brauner, Andrew Morton,
	Michal Hocko, Serge Hallyn, James Morris, Randy Dunlap,
	Suren Baghdasaryan, Yafang Shao, Helge Deller, Adrian Reber,
	Thomas Gleixner, Jens Axboe, Alexei Starovoitov,
	linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-kselftest, linux-mm, linux-security-module, tiozhang,
	Luis Chamberlain, Paulo Alcantara (SUSE), Sergey Senozhatsky,
	Frederic Weisbecker, YueHaibing, Paul Moore, Aleksa Sarai,
	Stefan Roesch, Chao Yu, xu xin, Jeff Layton, Jan Kara,
	David Hildenbrand, Dave Chinner, Shuah Khan, Elena Reshetova,
	David Windsor, Mateusz Guzik, Ard Biesheuvel,
	Joel Fernandes (Google), Matthew Wilcox (Oracle),
	Hans Liljestrand, Penglei Jiang, Lorenzo Stoakes, Adrian Ratiu,
	Ingo Molnar, Peter Zijlstra (Intel), Cyrill Gorcunov,
	Eric Dumazet, zohar, linux-integrity
In-Reply-To: <87h5uoxw06.fsf_-_@email.froward.int.ebiederm.org>

On Thu, 2025-11-20 at 14:57 -0600, Eric W. Biederman wrote:
> Instead of computing the new cred before we pass the point of no
> return compute the new cred just before we use it.
> 
> This allows the removal of fs_struct->in_exec and cred_guard_mutex.
> 
> I am not certain why we wanted to compute the cred for the new
> executable so early.  Perhaps I missed something but I did not see any
> common errors being signaled.   So I don't think we loose anything by
> computing the new cred later.
> 
> We gain a lot.
> 
> We stop holding the cred_guard_mutex over places where the code sleeps
> and waits for userspace.  These places include the waiting for the
> tracer in PTRACE_EVENT_EXIT, "put_user(0, tsk->clear_child_tid)" in
> mm_release, and "get_user(futex_offset, ...") in exit_robust_mutex.
> 
> We can remove fs_struct->in_exec.  The case where it was used simply
> never comes up, when we compute the cred after de_thread completes.
> 
> We remove the possibility of a hang between a tracer calling
> PTRACE_ATTACH/PTRACE_SIEZE and the kernel waiting for the tracer
> in PTRACE_EVENT_EXIT.
> 
> ---
> Oleg, Kees, Bernd, Can you see anything I am missing?

+ Mimi, linux-integrity (would be nice if we are in CC when linux-
security-module is in CC).

Apologies for not answering earlier, it seems I don't receive the
emails from the linux-security-module mailing list (thanks Serge for
letting me know!).

I tested your patch but there are a few warnings like this:

[    2.702374] =====================================
[    2.702854] WARNING: bad unlock balance detected!
[    2.703350] 6.18.0-rc6+ #409 Not tainted
[    2.703755] -------------------------------------
[    2.704241] init/1 is trying to release lock (init_fs.seq) at:
[    2.704829] [<ffffffff81836100>] begin_new_exec+0xfe0/0x1710
[    2.705421] but there are no more locks to release!
[    2.705931] 
[    2.705931] other info that might help us debug this:
[    2.706610] 1 lock held by init/1:
[    2.706958]  #0: ffff88810083e538 (&sig->exec_update_lock){+.+.}-{4:4}, at: begin_new_exec+0x769/0x1710

and then the system hangs.

I see two main effects of this patch. First, the bprm_check_security
hook implementations will not see bprm->cred populated. That was a
problem before we made this patch:

https://patchew.org/linux/20251008113503.2433343-1-roberto.sassu@huaweicloud.com/

to work around the problem of not calculating the final DAC credentials
early enough (well, we actually had to change our CREDS_CHECK hook
behavior).

The second, I could not check. If I remember well, unlike the
capability LSM, SELinux/Apparmor/SMACK calculate the final credentials
based on the first file being executed (thus the script, not the
interpreter). Is this patch keeping the same behavior despite preparing
the credentials when the final binary is found?

Thanks

Roberto

> The code compiles but I haven't test it yet.
> 
> I thought I was going to move commit_creds before de_thread, but that
> would have taken commit_cred out of exec_update_lock (which introduces
> races).
> 
> However I can't see any drawbacks of going the other direction.
> 
> 
>  fs/exec.c                    | 88 ++++++++++++++----------------------
>  fs/fs_struct.c               |  1 -
>  fs/proc/base.c               |  4 +-
>  include/linux/fs_struct.h    |  1 -
>  include/linux/sched/signal.h |  6 ---
>  init/init_task.c             |  1 -
>  kernel/cred.c                |  2 +-
>  kernel/fork.c                |  8 +---
>  kernel/ptrace.c              |  4 +-
>  kernel/seccomp.c             | 12 ++---
>  10 files changed, 45 insertions(+), 82 deletions(-)
> 
> diff --git a/fs/exec.c b/fs/exec.c
> index 4298e7e08d5d..5ae96584dab0 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -1090,6 +1090,9 @@ void __set_task_comm(struct task_struct *tsk, const char *buf, bool exec)
>  	perf_event_comm(tsk, exec);
>  }
>  
> +static int prepare_bprm_creds(struct linux_binprm *bprm);
> +static void check_unsafe_exec(struct linux_binprm *bprm);
> +
>  /*
>   * Calling this is the point of no return. None of the failures will be
>   * seen by userspace since either the process is already taking a fatal
> @@ -1101,10 +1104,6 @@ int begin_new_exec(struct linux_binprm * bprm)
>  	struct task_struct *me = current;
>  	int retval;
>  
> -	/* Once we are committed compute the creds */
> -	retval = bprm_creds_from_file(bprm);
> -	if (retval)
> -		return retval;
>  
>  	/*
>  	 * This tracepoint marks the point before flushing the old exec where
> @@ -1123,8 +1122,6 @@ int begin_new_exec(struct linux_binprm * bprm)
>  	retval = de_thread(me);
>  	if (retval)
>  		goto out;
> -	/* see the comment in check_unsafe_exec() */
> -	current->fs->in_exec = 0;
>  	/*
>  	 * Cancel any io_uring activity across execve
>  	 */
> @@ -1251,6 +1248,25 @@ int begin_new_exec(struct linux_binprm * bprm)
>  	WRITE_ONCE(me->self_exec_id, me->self_exec_id + 1);
>  	flush_signal_handlers(me, 0);
>  
> +	retval = prepare_bprm_creds(bprm);
> +	if (retval)
> +		goto out_unlock;
> +
> +	/*
> +	 * Check for unsafe execution states before exec_binprm(), which
> +	 * will call back into begin_new_exec(), into bprm_creds_from_file(),
> +	 * where setuid-ness is evaluated.
> +	 */
> +	check_unsafe_exec(bprm);
> +
> +	/* Set the unchanging part of bprm->cred */
> +	retval = security_bprm_creds_for_exec(bprm);
> +
> +	/* Once we are committed compute the creds */
> +	retval = bprm_creds_from_file(bprm);
> +	if (retval)
> +		goto out_unlock;
> +
>  	retval = set_cred_ucounts(bprm->cred);
>  	if (retval < 0)
>  		goto out_unlock;
> @@ -1272,9 +1288,9 @@ int begin_new_exec(struct linux_binprm * bprm)
>  	if (get_dumpable(me->mm) != SUID_DUMP_USER)
>  		perf_event_exit_task(me);
>  	/*
> -	 * cred_guard_mutex must be held at least to this point to prevent
> +	 * exec_update_lock must be held at least to this point to prevent
>  	 * ptrace_attach() from altering our determination of the task's
> -	 * credentials; any time after this it may be unlocked.
> +	 * credentials.
>  	 */
>  	security_bprm_committed_creds(bprm);
>  
> @@ -1291,8 +1307,6 @@ int begin_new_exec(struct linux_binprm * bprm)
>  
>  out_unlock:
>  	up_write(&me->signal->exec_update_lock);
> -	if (!bprm->cred)
> -		mutex_unlock(&me->signal->cred_guard_mutex);
>  
>  out:
>  	return retval;
> @@ -1336,7 +1350,6 @@ void setup_new_exec(struct linux_binprm * bprm)
>  	 */
>  	me->mm->task_size = TASK_SIZE;
>  	up_write(&me->signal->exec_update_lock);
> -	mutex_unlock(&me->signal->cred_guard_mutex);
>  }
>  EXPORT_SYMBOL(setup_new_exec);
>  
> @@ -1351,21 +1364,15 @@ void finalize_exec(struct linux_binprm *bprm)
>  EXPORT_SYMBOL(finalize_exec);
>  
>  /*
> - * Prepare credentials and lock ->cred_guard_mutex.
> - * setup_new_exec() commits the new creds and drops the lock.
> - * Or, if exec fails before, free_bprm() should release ->cred
> - * and unlock.
> + * Prepare credentials.  begin_new_exec() commits the new creds.
> + * Or, if exec fails before, free_bprm() should release ->cred.
>   */
>  static int prepare_bprm_creds(struct linux_binprm *bprm)
>  {
> -	if (mutex_lock_interruptible(&current->signal->cred_guard_mutex))
> -		return -ERESTARTNOINTR;
> -
>  	bprm->cred = prepare_exec_creds();
>  	if (likely(bprm->cred))
>  		return 0;
>  
> -	mutex_unlock(&current->signal->cred_guard_mutex);
>  	return -ENOMEM;
>  }
>  
> @@ -1386,9 +1393,7 @@ static void free_bprm(struct linux_binprm *bprm)
>  	}
>  	free_arg_pages(bprm);
>  	if (bprm->cred) {
> -		/* in case exec fails before de_thread() succeeds */
> -		current->fs->in_exec = 0;
> -		mutex_unlock(&current->signal->cred_guard_mutex);
> +		/* in case exec fails before commit_creds succeeds */
>  		abort_creds(bprm->cred);
>  	}
>  	do_close_execat(bprm->file);
> @@ -1486,13 +1491,12 @@ EXPORT_SYMBOL(bprm_change_interp);
>  
>  /*
>   * determine how safe it is to execute the proposed program
> - * - the caller must hold ->cred_guard_mutex to protect against
> + * - the caller must hold ->exec_update_lock to protect against
>   *   PTRACE_ATTACH or seccomp thread-sync
>   */
>  static void check_unsafe_exec(struct linux_binprm *bprm)
>  {
> -	struct task_struct *p = current, *t;
> -	unsigned n_fs;
> +	struct task_struct *p = current;
>  
>  	if (p->ptrace)
>  		bprm->unsafe |= LSM_UNSAFE_PTRACE;
> @@ -1509,25 +1513,9 @@ static void check_unsafe_exec(struct linux_binprm *bprm)
>  	 * suid exec because the differently privileged task
>  	 * will be able to manipulate the current directory, etc.
>  	 * It would be nice to force an unshare instead...
> -	 *
> -	 * Otherwise we set fs->in_exec = 1 to deny clone(CLONE_FS)
> -	 * from another sub-thread until de_thread() succeeds, this
> -	 * state is protected by cred_guard_mutex we hold.
>  	 */
> -	n_fs = 1;
> -	read_seqlock_excl(&p->fs->seq);
> -	rcu_read_lock();
> -	for_other_threads(p, t) {
> -		if (t->fs == p->fs)
> -			n_fs++;
> -	}
> -	rcu_read_unlock();
> -
> -	/* "users" and "in_exec" locked for copy_fs() */
> -	if (p->fs->users > n_fs)
> +	if (p->fs->users > 1)
>  		bprm->unsafe |= LSM_UNSAFE_SHARE;
> -	else
> -		p->fs->in_exec = 1;
>  	read_sequnlock_excl(&p->fs->seq);
>  }
>  
> @@ -1731,25 +1719,15 @@ static int bprm_execve(struct linux_binprm *bprm)
>  {
>  	int retval;
>  
> -	retval = prepare_bprm_creds(bprm);
> -	if (retval)
> -		return retval;
> +	if (bprm->is_check)
> +		return 0;
>  
> -	/*
> -	 * Check for unsafe execution states before exec_binprm(), which
> -	 * will call back into begin_new_exec(), into bprm_creds_from_file(),
> -	 * where setuid-ness is evaluated.
> -	 */
> -	check_unsafe_exec(bprm);
>  	current->in_execve = 1;
>  	sched_mm_cid_before_execve(current);
>  
>  	sched_exec();
>  
> -	/* Set the unchanging part of bprm->cred */
> -	retval = security_bprm_creds_for_exec(bprm);
> -	if (retval || bprm->is_check)
> -		goto out;
> +
>  
>  	retval = exec_binprm(bprm);
>  	if (retval < 0)
> diff --git a/fs/fs_struct.c b/fs/fs_struct.c
> index 28be762ac1c6..945bc0916f65 100644
> --- a/fs/fs_struct.c
> +++ b/fs/fs_struct.c
> @@ -109,7 +109,6 @@ struct fs_struct *copy_fs_struct(struct fs_struct *old)
>  	/* We don't need to lock fs - think why ;-) */
>  	if (fs) {
>  		fs->users = 1;
> -		fs->in_exec = 0;
>  		seqlock_init(&fs->seq);
>  		fs->umask = old->umask;
>  
> diff --git a/fs/proc/base.c b/fs/proc/base.c
> index 6299878e3d97..7041fb4d1689 100644
> --- a/fs/proc/base.c
> +++ b/fs/proc/base.c
> @@ -2834,14 +2834,14 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
>  	}
>  
>  	/* Guard against adverse ptrace interaction */
> -	rv = mutex_lock_interruptible(&current->signal->cred_guard_mutex);
> +	rv = down_write_killable(&current->signal->exec_update_lock);
>  	if (rv < 0)
>  		goto out_free;
>  
>  	rv = security_setprocattr(PROC_I(inode)->op.lsmid,
>  				  file->f_path.dentry->d_name.name, page,
>  				  count);
> -	mutex_unlock(&current->signal->cred_guard_mutex);
> +	up_write(&current->signal->exec_update_lock);
>  out_free:
>  	kfree(page);
>  out:
> diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h
> index baf200ab5c77..29d0f7d57743 100644
> --- a/include/linux/fs_struct.h
> +++ b/include/linux/fs_struct.h
> @@ -10,7 +10,6 @@ struct fs_struct {
>  	int users;
>  	seqlock_t seq;
>  	int umask;
> -	int in_exec;
>  	struct path root, pwd;
>  } __randomize_layout;
>  
> diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h
> index 7d6449982822..7e9259c8fb2b 100644
> --- a/include/linux/sched/signal.h
> +++ b/include/linux/sched/signal.h
> @@ -241,12 +241,6 @@ struct signal_struct {
>  	struct mm_struct *oom_mm;	/* recorded mm when the thread group got
>  					 * killed by the oom killer */
>  
> -	struct mutex cred_guard_mutex;	/* guard against foreign influences on
> -					 * credential calculations
> -					 * (notably. ptrace)
> -					 * Deprecated do not use in new code.
> -					 * Use exec_update_lock instead.
> -					 */
>  	struct rw_semaphore exec_update_lock;	/* Held while task_struct is
>  						 * being updated during exec,
>  						 * and may have inconsistent
> diff --git a/init/init_task.c b/init/init_task.c
> index a55e2189206f..4813bffe217e 100644
> --- a/init/init_task.c
> +++ b/init/init_task.c
> @@ -30,7 +30,6 @@ static struct signal_struct init_signals = {
>  #ifdef CONFIG_CGROUPS
>  	.cgroup_threadgroup_rwsem	= __RWSEM_INITIALIZER(init_signals.cgroup_threadgroup_rwsem),
>  #endif
> -	.cred_guard_mutex = __MUTEX_INITIALIZER(init_signals.cred_guard_mutex),
>  	.exec_update_lock = __RWSEM_INITIALIZER(init_signals.exec_update_lock),
>  #ifdef CONFIG_POSIX_TIMERS
>  	.posix_timers		= HLIST_HEAD_INIT,
> diff --git a/kernel/cred.c b/kernel/cred.c
> index dbf6b687dc5c..80e376ce005f 100644
> --- a/kernel/cred.c
> +++ b/kernel/cred.c
> @@ -252,7 +252,7 @@ EXPORT_SYMBOL(prepare_creds);
>  
>  /*
>   * Prepare credentials for current to perform an execve()
> - * - The caller must hold ->cred_guard_mutex
> + * - The caller must hold ->exec_update_lock
>   */
>  struct cred *prepare_exec_creds(void)
>  {
> diff --git a/kernel/fork.c b/kernel/fork.c
> index 3da0f08615a9..996c649b9a4c 100644
> --- a/kernel/fork.c
> +++ b/kernel/fork.c
> @@ -1555,11 +1555,6 @@ static int copy_fs(u64 clone_flags, struct task_struct *tsk)
>  	if (clone_flags & CLONE_FS) {
>  		/* tsk->fs is already what we want */
>  		read_seqlock_excl(&fs->seq);
> -		/* "users" and "in_exec" locked for check_unsafe_exec() */
> -		if (fs->in_exec) {
> -			read_sequnlock_excl(&fs->seq);
> -			return -EAGAIN;
> -		}
>  		fs->users++;
>  		read_sequnlock_excl(&fs->seq);
>  		return 0;
> @@ -1699,7 +1694,6 @@ static int copy_signal(u64 clone_flags, struct task_struct *tsk)
>  	sig->oom_score_adj = current->signal->oom_score_adj;
>  	sig->oom_score_adj_min = current->signal->oom_score_adj_min;
>  
> -	mutex_init(&sig->cred_guard_mutex);
>  	init_rwsem(&sig->exec_update_lock);
>  
>  	return 0;
> @@ -1710,7 +1704,7 @@ static void copy_seccomp(struct task_struct *p)
>  #ifdef CONFIG_SECCOMP
>  	/*
>  	 * Must be called with sighand->lock held, which is common to
> -	 * all threads in the group. Holding cred_guard_mutex is not
> +	 * all threads in the group. Holding exec_update_lock is not
>  	 * needed because this new task is not yet running and cannot
>  	 * be racing exec.
>  	 */
> diff --git a/kernel/ptrace.c b/kernel/ptrace.c
> index 75a84efad40f..8140d4bfc279 100644
> --- a/kernel/ptrace.c
> +++ b/kernel/ptrace.c
> @@ -444,8 +444,8 @@ static int ptrace_attach(struct task_struct *task, long request,
>  	 * SUID, SGID and LSM creds get determined differently
>  	 * under ptrace.
>  	 */
> -	scoped_cond_guard (mutex_intr, return -ERESTARTNOINTR,
> -			   &task->signal->cred_guard_mutex) {
> +	scoped_cond_guard (rwsem_read_intr, return -ERESTARTNOINTR,
> +			   &task->signal->exec_update_lock) {
>  
>  		scoped_guard (task_lock, task) {
>  			retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH_REALCREDS);
> diff --git a/kernel/seccomp.c b/kernel/seccomp.c
> index 25f62867a16d..87de8d47d876 100644
> --- a/kernel/seccomp.c
> +++ b/kernel/seccomp.c
> @@ -479,7 +479,7 @@ static int is_ancestor(struct seccomp_filter *parent,
>  /**
>   * seccomp_can_sync_threads: checks if all threads can be synchronized
>   *
> - * Expects sighand and cred_guard_mutex locks to be held.
> + * Expects sighand and exec_update_lock locks to be held.
>   *
>   * Returns 0 on success, -ve on error, or the pid of a thread which was
>   * either not in the correct seccomp mode or did not have an ancestral
> @@ -489,7 +489,7 @@ static inline pid_t seccomp_can_sync_threads(void)
>  {
>  	struct task_struct *thread, *caller;
>  
> -	BUG_ON(!mutex_is_locked(&current->signal->cred_guard_mutex));
> +	BUG_ON(!rwsem_is_locked(&current->signal->exec_update_lock));
>  	assert_spin_locked(&current->sighand->siglock);
>  
>  	/* Validate all threads being eligible for synchronization. */
> @@ -590,7 +590,7 @@ void seccomp_filter_release(struct task_struct *tsk)
>   *
>   * @flags: SECCOMP_FILTER_FLAG_* flags to set during sync.
>   *
> - * Expects sighand and cred_guard_mutex locks to be held, and for
> + * Expects sighand and exec_update_lock locks to be held, and for
>   * seccomp_can_sync_threads() to have returned success already
>   * without dropping the locks.
>   *
> @@ -599,7 +599,7 @@ static inline void seccomp_sync_threads(unsigned long flags)
>  {
>  	struct task_struct *thread, *caller;
>  
> -	BUG_ON(!mutex_is_locked(&current->signal->cred_guard_mutex));
> +	BUG_ON(!rwsem_is_locked(&current->signal->exec_update_lock));
>  	assert_spin_locked(&current->sighand->siglock);
>  
>  	/*
> @@ -2011,7 +2011,7 @@ static long seccomp_set_mode_filter(unsigned int flags,
>  	 * while another thread is in the middle of calling exec.
>  	 */
>  	if (flags & SECCOMP_FILTER_FLAG_TSYNC &&
> -	    mutex_lock_killable(&current->signal->cred_guard_mutex))
> +	    down_read_killable(&current->signal->exec_update_lock))
>  		goto out_put_fd;
>  
>  	spin_lock_irq(&current->sighand->siglock);
> @@ -2034,7 +2034,7 @@ static long seccomp_set_mode_filter(unsigned int flags,
>  out:
>  	spin_unlock_irq(&current->sighand->siglock);
>  	if (flags & SECCOMP_FILTER_FLAG_TSYNC)
> -		mutex_unlock(&current->signal->cred_guard_mutex);
> +		up_read(&current->signal->exec_update_lock);
>  out_put_fd:
>  	if (flags & SECCOMP_FILTER_FLAG_NEW_LISTENER) {
>  		if (ret) {


^ permalink raw reply

* Re: [PATCHv2 1/2] kernel/kexec: Change the prototype of kimage_map_segment()
From: Baoquan He @ 2025-11-25  4:54 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Pingfan Liu, kexec, linux-integrity, Mimi Zohar, Roberto Sassu,
	Alexander Graf, Steven Chen, stable
In-Reply-To: <20251124141620.eaef984836fe2edc7acf9179@linux-foundation.org>

On 11/24/25 at 02:16pm, Andrew Morton wrote:
> On Thu,  6 Nov 2025 14:59:03 +0800 Pingfan Liu <piliu@redhat.com> wrote:
> 
> > The kexec segment index will be required to extract the corresponding
> > information for that segment in kimage_map_segment(). Additionally,
> > kexec_segment already holds the kexec relocation destination address and
> > size. Therefore, the prototype of kimage_map_segment() can be changed.
> 
> Could we please have some reviewer input on thee two patches?

I have some concerns about the one place of tiny code change, and the
root cause missing in log. And Mimi sent mail to me asking why this bug
can'e be seen on her laptop, I told her this bug can only be triggered
on system where CMA area exists. I think these need be addressed in v3.

> 
> (Pingfan, please cc linux-kernel on patches - it's where people go to
> find emails on lists which they aren't suscribed to)
> 
> (akpm goes off and subscribes to kexec@)
> 
> > Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
> > Signed-off-by: Pingfan Liu <piliu@redhat.com>
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Baoquan He <bhe@redhat.com>
> > Cc: Mimi Zohar <zohar@linux.ibm.com>
> > Cc: Roberto Sassu <roberto.sassu@huawei.com>
> > Cc: Alexander Graf <graf@amazon.com>
> > Cc: Steven Chen <chenste@linux.microsoft.com>
> > Cc: <stable@vger.kernel.org>
> > To: kexec@lists.infradead.org
> > To: linux-integrity@vger.kernel.org
> > ---
> >  include/linux/kexec.h              | 4 ++--
> >  kernel/kexec_core.c                | 9 ++++++---
> >  security/integrity/ima/ima_kexec.c | 4 +---
> >  3 files changed, 9 insertions(+), 8 deletions(-)
> > 
> > diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> > index ff7e231b0485..8a22bc9b8c6c 100644
> > --- a/include/linux/kexec.h
> > +++ b/include/linux/kexec.h
> > @@ -530,7 +530,7 @@ extern bool kexec_file_dbg_print;
> >  #define kexec_dprintk(fmt, arg...) \
> >          do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0)
> >  
> > -extern void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size);
> > +extern void *kimage_map_segment(struct kimage *image, int idx);
> >  extern void kimage_unmap_segment(void *buffer);
> >  #else /* !CONFIG_KEXEC_CORE */
> >  struct pt_regs;
> > @@ -540,7 +540,7 @@ static inline void __crash_kexec(struct pt_regs *regs) { }
> >  static inline void crash_kexec(struct pt_regs *regs) { }
> >  static inline int kexec_should_crash(struct task_struct *p) { return 0; }
> >  static inline int kexec_crash_loaded(void) { return 0; }
> > -static inline void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size)
> > +static inline void *kimage_map_segment(struct kimage *image, int idx)
> >  { return NULL; }
> >  static inline void kimage_unmap_segment(void *buffer) { }
> >  #define kexec_in_progress false
> > diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> > index fa00b239c5d9..9a1966207041 100644
> > --- a/kernel/kexec_core.c
> > +++ b/kernel/kexec_core.c
> > @@ -960,17 +960,20 @@ int kimage_load_segment(struct kimage *image, int idx)
> >  	return result;
> >  }
> >  
> > -void *kimage_map_segment(struct kimage *image,
> > -			 unsigned long addr, unsigned long size)
> > +void *kimage_map_segment(struct kimage *image, int idx)
> >  {
> > +	unsigned long addr, size, eaddr;
> >  	unsigned long src_page_addr, dest_page_addr = 0;
> > -	unsigned long eaddr = addr + size;
> >  	kimage_entry_t *ptr, entry;
> >  	struct page **src_pages;
> >  	unsigned int npages;
> >  	void *vaddr = NULL;
> >  	int i;
> >  
> > +	addr = image->segment[idx].mem;
> > +	size = image->segment[idx].memsz;
> > +	eaddr = addr + size;
> > +
> >  	/*
> >  	 * Collect the source pages and map them in a contiguous VA range.
> >  	 */
> > diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> > index 7362f68f2d8b..5beb69edd12f 100644
> > --- a/security/integrity/ima/ima_kexec.c
> > +++ b/security/integrity/ima/ima_kexec.c
> > @@ -250,9 +250,7 @@ void ima_kexec_post_load(struct kimage *image)
> >  	if (!image->ima_buffer_addr)
> >  		return;
> >  
> > -	ima_kexec_buffer = kimage_map_segment(image,
> > -					      image->ima_buffer_addr,
> > -					      image->ima_buffer_size);
> > +	ima_kexec_buffer = kimage_map_segment(image, image->ima_segment_index);
> >  	if (!ima_kexec_buffer) {
> >  		pr_err("Could not map measurements buffer.\n");
> >  		return;
> > -- 
> > 2.49.0
> 


^ permalink raw reply

* Re: [PATCHv2 1/2] kernel/kexec: Change the prototype of kimage_map_segment()
From: Pingfan Liu @ 2025-11-25  4:10 UTC (permalink / raw)
  To: Andrew Morton
  Cc: kexec, linux-integrity, Baoquan He, Mimi Zohar, Roberto Sassu,
	Alexander Graf, Steven Chen, stable
In-Reply-To: <20251124141620.eaef984836fe2edc7acf9179@linux-foundation.org>

On Tue, Nov 25, 2025 at 6:16 AM Andrew Morton <akpm@linux-foundation.org> wrote:
>
> On Thu,  6 Nov 2025 14:59:03 +0800 Pingfan Liu <piliu@redhat.com> wrote:
>
> > The kexec segment index will be required to extract the corresponding
> > information for that segment in kimage_map_segment(). Additionally,
> > kexec_segment already holds the kexec relocation destination address and
> > size. Therefore, the prototype of kimage_map_segment() can be changed.
>
> Could we please have some reviewer input on thee two patches?
>
> Thanks.
>
> (Pingfan, please cc linux-kernel on patches - it's where people go to
> find emails on lists which they aren't suscribed to)
>
OK, I will cc linux-kernel for the future kexec patches

For this series, it can also be found on
https://lore.kernel.org/linux-integrity/20251106065904.10772-1-piliu@redhat.com/

Thanks,

Pingfan

> (akpm goes off and subscribes to kexec@)
>
> > Fixes: 07d24902977e ("kexec: enable CMA based contiguous allocation")
> > Signed-off-by: Pingfan Liu <piliu@redhat.com>
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Baoquan He <bhe@redhat.com>
> > Cc: Mimi Zohar <zohar@linux.ibm.com>
> > Cc: Roberto Sassu <roberto.sassu@huawei.com>
> > Cc: Alexander Graf <graf@amazon.com>
> > Cc: Steven Chen <chenste@linux.microsoft.com>
> > Cc: <stable@vger.kernel.org>
> > To: kexec@lists.infradead.org
> > To: linux-integrity@vger.kernel.org
> > ---
> >  include/linux/kexec.h              | 4 ++--
> >  kernel/kexec_core.c                | 9 ++++++---
> >  security/integrity/ima/ima_kexec.c | 4 +---
> >  3 files changed, 9 insertions(+), 8 deletions(-)
> >
> > diff --git a/include/linux/kexec.h b/include/linux/kexec.h
> > index ff7e231b0485..8a22bc9b8c6c 100644
> > --- a/include/linux/kexec.h
> > +++ b/include/linux/kexec.h
> > @@ -530,7 +530,7 @@ extern bool kexec_file_dbg_print;
> >  #define kexec_dprintk(fmt, arg...) \
> >          do { if (kexec_file_dbg_print) pr_info(fmt, ##arg); } while (0)
> >
> > -extern void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size);
> > +extern void *kimage_map_segment(struct kimage *image, int idx);
> >  extern void kimage_unmap_segment(void *buffer);
> >  #else /* !CONFIG_KEXEC_CORE */
> >  struct pt_regs;
> > @@ -540,7 +540,7 @@ static inline void __crash_kexec(struct pt_regs *regs) { }
> >  static inline void crash_kexec(struct pt_regs *regs) { }
> >  static inline int kexec_should_crash(struct task_struct *p) { return 0; }
> >  static inline int kexec_crash_loaded(void) { return 0; }
> > -static inline void *kimage_map_segment(struct kimage *image, unsigned long addr, unsigned long size)
> > +static inline void *kimage_map_segment(struct kimage *image, int idx)
> >  { return NULL; }
> >  static inline void kimage_unmap_segment(void *buffer) { }
> >  #define kexec_in_progress false
> > diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
> > index fa00b239c5d9..9a1966207041 100644
> > --- a/kernel/kexec_core.c
> > +++ b/kernel/kexec_core.c
> > @@ -960,17 +960,20 @@ int kimage_load_segment(struct kimage *image, int idx)
> >       return result;
> >  }
> >
> > -void *kimage_map_segment(struct kimage *image,
> > -                      unsigned long addr, unsigned long size)
> > +void *kimage_map_segment(struct kimage *image, int idx)
> >  {
> > +     unsigned long addr, size, eaddr;
> >       unsigned long src_page_addr, dest_page_addr = 0;
> > -     unsigned long eaddr = addr + size;
> >       kimage_entry_t *ptr, entry;
> >       struct page **src_pages;
> >       unsigned int npages;
> >       void *vaddr = NULL;
> >       int i;
> >
> > +     addr = image->segment[idx].mem;
> > +     size = image->segment[idx].memsz;
> > +     eaddr = addr + size;
> > +
> >       /*
> >        * Collect the source pages and map them in a contiguous VA range.
> >        */
> > diff --git a/security/integrity/ima/ima_kexec.c b/security/integrity/ima/ima_kexec.c
> > index 7362f68f2d8b..5beb69edd12f 100644
> > --- a/security/integrity/ima/ima_kexec.c
> > +++ b/security/integrity/ima/ima_kexec.c
> > @@ -250,9 +250,7 @@ void ima_kexec_post_load(struct kimage *image)
> >       if (!image->ima_buffer_addr)
> >               return;
> >
> > -     ima_kexec_buffer = kimage_map_segment(image,
> > -                                           image->ima_buffer_addr,
> > -                                           image->ima_buffer_size);
> > +     ima_kexec_buffer = kimage_map_segment(image, image->ima_segment_index);
> >       if (!ima_kexec_buffer) {
> >               pr_err("Could not map measurements buffer.\n");
> >               return;
> > --
> > 2.49.0
>


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox