* Re: [PATCH v3 3/3] ima: Add support for staging measurements for deletion
From: Mimi Zohar @ 2026-03-17 21:03 UTC (permalink / raw)
To: Roberto Sassu, corbet, skhan, dmitry.kasatkin, eric.snowberg,
paul, jmorris, serge
Cc: linux-doc, linux-kernel, linux-integrity, linux-security-module,
gregorylumen, chenste, nramas, Roberto Sassu
In-Reply-To: <20260311171956.2317781-3-roberto.sassu@huaweicloud.com>
Hi Roberto,
On Wed, 2026-03-11 at 18:19 +0100, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
>
> Introduce the ability of staging the IMA measurement list for deletion.
> Staging means moving the current content of the measurement list to a
> separate location, and allowing users to read and delete it. This causes
> the measurement list to be atomically truncated before new measurements can
> be added.
I really like this design of atomically moving and subsequently deleting the
measurement list. However this is a solution, not the motivation for the patch.
Please include the motivation for the patch, before describing the solution.
> Staging can be done only once at a time. In the event of kexec(),
> staging is reverted and staged entries will be carried over to the new
> kernel.
>
> Staged measurements can be deleted entirely, or partially, with the
> non-deleted ones added back to the IMA measurements list.
This patch description is really long, which is an indication that the patch
needs to be split up. Adding support for partially deleting the measurement
list records, by prepending the remaining measurement records, should be a
separate patch.
> This allows the
> remote attestation agents to easily separate the measurements that where
> verified (staged and deleted) from those that weren't due to the race
> between taking a TPM quote and reading the measurements list.
>
> User space is responsible to concatenate the staged IMA measurements list
> portions (excluding the measurements added back to the IMA measurements
> list) following the temporal order in which the operations were done,
> together with the current measurement list. Then, it can send the collected
> data to the remote verifiers.
This belongs in a Documentation patch.
>
> The benefit of staging and deleting is the ability to free precious kernel
> memory,
This is the motivation for the patch.
> in exchange of delegating user space to reconstruct the full
> measurement list from the chunks. No trust needs to be given to user space,
> since the integrity of the measurement list is protected by the TPM.
Agreed the measurement list, itself, is protected by the TPM. However, relying
on userspace to reassemble the chunks is another concern. Support for staging
and deleting the measurement list should be configurable. Defining a Kconfig
should be part of this initial patch.
> By default, staging the measurements list does not alter the hash table.
> When staging and deleting are done, IMA is still able to detect collisions
> on the staged and later deleted measurement entries, by keeping the entry
> digests (only template data are freed).
>
> However, since during the measurements list serialization only the SHA1
> digest is passed, and since there are no template data to recalculate the
> other digests from, the hash table is currently not populated with digests
> from staged/deleted entries after kexec().
>
> Introduce the new kernel option ima_flush_htable to decide whether or not
> the digests of staged measurement entries are flushed from the hash table,
> when they are deleted. Flushing the hash table is supported only when
> deleting all the staged measurements, since in that case the old hash table
> can be quickly swapped with a blank one (otherwise entries would have to be
> removed one by one for partial deletion).
Allowing the hash table to be deleted would be an example of another patch.
>
> Then, introduce ascii_runtime_measurements_<algo>_staged and
> binary_runtime_measurements_<algo>_staged interfaces to stage and delete
> the measurements. Use 'echo A > <IMA interface>' and
> 'echo D > <IMA interface>' to respectively stage and delete the entire
> measurements list. Use 'echo N > <IMA interface>', with N between 1 and
> ULONG_MAX - 1, to delete the selected staged portion of the measurements
> list.
>
> The ima_measure_users counter (protected by the ima_measure_mutex mutex)
> has been introduced to protect access to the measurements list and the
> staged part. The open method of all the measurement interfaces has been
> extended to allow only one writer at a time or, in alternative, multiple
> readers. The write permission is used to stage and delete the measurements,
> the read permission to read them. Write requires also the CAP_SYS_ADMIN
> capability.
Yes, this is part of the initial patch that adds support for staging the
measurement list.
>
> Finally, introduce the binary_lists enum and make binary_runtime_size
> and ima_num_entries as arrays, to keep track of their values for the
> current IMA measurements list (BINARY), current list plus staged
> measurements (BINARY_STAGED) and the cumulative list since IMA
> initialization (BINARY_FULL).
>
> Use BINARY in ima_show_measurements_count(), BINARY_STAGED in
> ima_add_kexec_buffer() and BINARY_FULL in ima_measure_kexec_event().
>
> It should be noted that the BINARY_FULL counter is not passed through
> kexec. Thus, the number of entries included in the kexec critical data
> records refers to the entries since the previous kexec records.
>
> Note: This code derives from the Alt-IMA Huawei project, whose license is
> GPL-2.0 OR MIT.
>
> Link: https://github.com/linux-integrity/linux/issues/1
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
The design looks good. As I mentioned above, this patch description is quite
long, which is an indication that the patch needs to be split up. One method of
breaking it up would be:
- (Basic) support for staging measurements for deletion (based on a Kconfig)
- Support for removing the hash table
- Support for deleting N measurement records (and pre-pending the remaining
measurement records)
- Adding documentation
thanks,
Mimi
^ permalink raw reply
* Re: [PATCH v3 1/3] ima: Remove ima_h_table structure
From: Mimi Zohar @ 2026-03-17 19:15 UTC (permalink / raw)
To: Roberto Sassu, corbet, skhan, dmitry.kasatkin, eric.snowberg,
paul, jmorris, serge
Cc: linux-doc, linux-kernel, linux-integrity, linux-security-module,
gregorylumen, chenste, nramas, Roberto Sassu
In-Reply-To: <20260311171956.2317781-1-roberto.sassu@huaweicloud.com>
On Wed, 2026-03-11 at 18:19 +0100, Roberto Sassu wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
>
> With the upcoming change of dynamically allocating and replacing the hash
> table, we would need to keep the counters for number of measurements
> entries and violations.
>
> Since anyway, those counters don't belong there, remove the ima_h_table
> structure instead and move the counters and the hash table as a separate
> variables.
There's no cover letter or motivation in this patch description for needing to
"dynamically allocating or replacing the existing hash table."
Saying that the htable, number of records in the measurement list, and violation
counter don't belong grouped together is insufficient. There must have been a
valid reason for why they were grouped together originally (e.g. never removed
or reset).
Please provide a motivation for removing the ima_h_table struct and its usage
and defining them independently of each other.
thanks,
Mimi
^ permalink raw reply
* [PATCH 3/4] tpm: Move TPM2 specific definitions to the command header
From: Alec Brown @ 2026-03-17 16:03 UTC (permalink / raw)
To: linux-kernel, linux-integrity, jarkko
Cc: peterhuewe, jarkko.sakkinen, jgg, ross.philipson, dpsmith,
daniel.kiper, kanth.ghatraju, trenchboot-devel, ardb,
alec.r.brown
In-Reply-To: <20260317160613.2899129-1-alec.r.brown@oracle.com>
From: Ross Philipson <ross.philipson@oracle.com>
From: Ross Philipson <ross.philipson@oracle.com>
Gather all the TPM2 definitions and structures in the internal header
file drivers/char/tpm/tpm.h into the command header, including:
- Command codes, return codes and definitions from the public and
internal tpm.h files.
- Structures defined in numerous TPM driver C modules.
The definitions moved to these files correspond to the TCG specification
for TPM 2 family:
TPM 2.0 Library
- https://trustedcomputinggroup.org/resource/tpm-library-specification/
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
---
drivers/char/tpm/tpm.h | 77 ----------
drivers/char/tpm/tpm2-cmd.c | 30 ----
drivers/char/tpm/tpm2-space.c | 13 --
include/linux/tpm.h | 145 ------------------
include/linux/tpm_command.h | 273 ++++++++++++++++++++++++++++++++++
5 files changed, 273 insertions(+), 265 deletions(-)
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 1a9a46a921fe..147e57c0e7bb 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -51,83 +51,6 @@ enum tpm_addr {
TPM_ADDR = 0x4E,
};
-/* TPM2 specific constants. */
-#define TPM2_SPACE_BUFFER_SIZE 16384 /* 16 kB */
-
-enum tpm2_pt_props {
- TPM2_PT_NONE = 0x00000000,
- TPM2_PT_GROUP = 0x00000100,
- TPM2_PT_FIXED = TPM2_PT_GROUP * 1,
- TPM2_PT_FAMILY_INDICATOR = TPM2_PT_FIXED + 0,
- TPM2_PT_LEVEL = TPM2_PT_FIXED + 1,
- TPM2_PT_REVISION = TPM2_PT_FIXED + 2,
- TPM2_PT_DAY_OF_YEAR = TPM2_PT_FIXED + 3,
- TPM2_PT_YEAR = TPM2_PT_FIXED + 4,
- TPM2_PT_MANUFACTURER = TPM2_PT_FIXED + 5,
- TPM2_PT_VENDOR_STRING_1 = TPM2_PT_FIXED + 6,
- TPM2_PT_VENDOR_STRING_2 = TPM2_PT_FIXED + 7,
- TPM2_PT_VENDOR_STRING_3 = TPM2_PT_FIXED + 8,
- TPM2_PT_VENDOR_STRING_4 = TPM2_PT_FIXED + 9,
- TPM2_PT_VENDOR_TPM_TYPE = TPM2_PT_FIXED + 10,
- TPM2_PT_FIRMWARE_VERSION_1 = TPM2_PT_FIXED + 11,
- TPM2_PT_FIRMWARE_VERSION_2 = TPM2_PT_FIXED + 12,
- TPM2_PT_INPUT_BUFFER = TPM2_PT_FIXED + 13,
- TPM2_PT_HR_TRANSIENT_MIN = TPM2_PT_FIXED + 14,
- TPM2_PT_HR_PERSISTENT_MIN = TPM2_PT_FIXED + 15,
- TPM2_PT_HR_LOADED_MIN = TPM2_PT_FIXED + 16,
- TPM2_PT_ACTIVE_SESSIONS_MAX = TPM2_PT_FIXED + 17,
- TPM2_PT_PCR_COUNT = TPM2_PT_FIXED + 18,
- TPM2_PT_PCR_SELECT_MIN = TPM2_PT_FIXED + 19,
- TPM2_PT_CONTEXT_GAP_MAX = TPM2_PT_FIXED + 20,
- TPM2_PT_NV_COUNTERS_MAX = TPM2_PT_FIXED + 22,
- TPM2_PT_NV_INDEX_MAX = TPM2_PT_FIXED + 23,
- TPM2_PT_MEMORY = TPM2_PT_FIXED + 24,
- TPM2_PT_CLOCK_UPDATE = TPM2_PT_FIXED + 25,
- TPM2_PT_CONTEXT_HASH = TPM2_PT_FIXED + 26,
- TPM2_PT_CONTEXT_SYM = TPM2_PT_FIXED + 27,
- TPM2_PT_CONTEXT_SYM_SIZE = TPM2_PT_FIXED + 28,
- TPM2_PT_ORDERLY_COUNT = TPM2_PT_FIXED + 29,
- TPM2_PT_MAX_COMMAND_SIZE = TPM2_PT_FIXED + 30,
- TPM2_PT_MAX_RESPONSE_SIZE = TPM2_PT_FIXED + 31,
- TPM2_PT_MAX_DIGEST = TPM2_PT_FIXED + 32,
- TPM2_PT_MAX_OBJECT_CONTEXT = TPM2_PT_FIXED + 33,
- TPM2_PT_MAX_SESSION_CONTEXT = TPM2_PT_FIXED + 34,
- TPM2_PT_PS_FAMILY_INDICATOR = TPM2_PT_FIXED + 35,
- TPM2_PT_PS_LEVEL = TPM2_PT_FIXED + 36,
- TPM2_PT_PS_REVISION = TPM2_PT_FIXED + 37,
- TPM2_PT_PS_DAY_OF_YEAR = TPM2_PT_FIXED + 38,
- TPM2_PT_PS_YEAR = TPM2_PT_FIXED + 39,
- TPM2_PT_SPLIT_MAX = TPM2_PT_FIXED + 40,
- TPM2_PT_TOTAL_COMMANDS = TPM2_PT_FIXED + 41,
- TPM2_PT_LIBRARY_COMMANDS = TPM2_PT_FIXED + 42,
- TPM2_PT_VENDOR_COMMANDS = TPM2_PT_FIXED + 43,
- TPM2_PT_NV_BUFFER_MAX = TPM2_PT_FIXED + 44,
- TPM2_PT_MODES = TPM2_PT_FIXED + 45,
- TPM2_PT_MAX_CAP_BUFFER = TPM2_PT_FIXED + 46,
- TPM2_PT_VAR = TPM2_PT_GROUP * 2,
- TPM2_PT_PERMANENT = TPM2_PT_VAR + 0,
- TPM2_PT_STARTUP_CLEAR = TPM2_PT_VAR + 1,
- TPM2_PT_HR_NV_INDEX = TPM2_PT_VAR + 2,
- TPM2_PT_HR_LOADED = TPM2_PT_VAR + 3,
- TPM2_PT_HR_LOADED_AVAIL = TPM2_PT_VAR + 4,
- TPM2_PT_HR_ACTIVE = TPM2_PT_VAR + 5,
- TPM2_PT_HR_ACTIVE_AVAIL = TPM2_PT_VAR + 6,
- TPM2_PT_HR_TRANSIENT_AVAIL = TPM2_PT_VAR + 7,
- TPM2_PT_HR_PERSISTENT = TPM2_PT_VAR + 8,
- TPM2_PT_HR_PERSISTENT_AVAIL = TPM2_PT_VAR + 9,
- TPM2_PT_NV_COUNTERS = TPM2_PT_VAR + 10,
- TPM2_PT_NV_COUNTERS_AVAIL = TPM2_PT_VAR + 11,
- TPM2_PT_ALGORITHM_SET = TPM2_PT_VAR + 12,
- TPM2_PT_LOADED_CURVES = TPM2_PT_VAR + 13,
- TPM2_PT_LOCKOUT_COUNTER = TPM2_PT_VAR + 14,
- TPM2_PT_MAX_AUTH_FAIL = TPM2_PT_VAR + 15,
- TPM2_PT_LOCKOUT_INTERVAL = TPM2_PT_VAR + 16,
- TPM2_PT_LOCKOUT_RECOVERY = TPM2_PT_VAR + 17,
- TPM2_PT_NV_WRITE_RECOVERY = TPM2_PT_VAR + 18,
- TPM2_PT_AUDIT_COUNTER_0 = TPM2_PT_VAR + 19,
- TPM2_PT_AUDIT_COUNTER_1 = TPM2_PT_VAR + 20,
-};
-
extern const struct class tpm_class;
extern const struct class tpmrm_class;
extern dev_t tpm_devt;
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 3a77be7ebf4a..1fa3e8a43c79 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -94,17 +94,6 @@ unsigned long tpm2_calc_ordinal_duration(u32 ordinal)
return msecs_to_jiffies(TPM2_DURATION_DEFAULT);
}
-struct tpm2_pcr_read_out {
- __be32 update_cnt;
- __be32 pcr_selects_cnt;
- __be16 hash_alg;
- u8 pcr_select_size;
- u8 pcr_select[TPM2_PCR_SELECT_MIN];
- __be32 digests_cnt;
- __be16 digest_size;
- u8 digest[];
-} __packed;
-
/**
* tpm2_pcr_read() - read a PCR value
* @chip: TPM chip to use.
@@ -238,11 +227,6 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
return rc;
}
-struct tpm2_get_random_out {
- __be16 size;
- u8 buffer[TPM_MAX_RNG_DATA];
-} __packed;
-
/**
* tpm2_get_random() - get random bytes from the TPM RNG
*
@@ -366,14 +350,6 @@ void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
}
EXPORT_SYMBOL_GPL(tpm2_flush_context);
-struct tpm2_get_cap_out {
- u8 more_data;
- __be32 subcap_id;
- __be32 property_cnt;
- __be32 property_id;
- __be32 value;
-} __packed;
-
/**
* tpm2_get_tpm_pt() - get value of a TPM_CAP_TPM_PROPERTIES type property
* @chip: a &tpm_chip instance
@@ -541,12 +517,6 @@ static int tpm2_init_bank_info(struct tpm_chip *chip, u32 bank_index)
return tpm2_pcr_read(chip, 0, &digest, &bank->digest_size);
}
-struct tpm2_pcr_selection {
- __be16 hash_alg;
- u8 size_of_select;
- u8 pcr_select[3];
-} __packed;
-
ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
{
struct tpm2_pcr_selection pcr_selection;
diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index 60354cd53b5c..7c1c0a174a2b 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -15,19 +15,6 @@
#include <linux/unaligned.h>
#include "tpm.h"
-enum tpm2_handle_types {
- TPM2_HT_HMAC_SESSION = 0x02000000,
- TPM2_HT_POLICY_SESSION = 0x03000000,
- TPM2_HT_TRANSIENT = 0x80000000,
-};
-
-struct tpm2_context {
- __be64 sequence;
- __be32 saved_handle;
- __be32 hierarchy;
- __be16 blob_size;
-} __packed;
-
static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
{
int i;
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 18dcf0ef46f6..92957452f7a7 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -38,12 +38,6 @@ struct trusted_key_options;
/* opaque structure, holds auth session parameters like the session key */
struct tpm2_auth;
-enum tpm2_session_types {
- TPM2_SE_HMAC = 0x00,
- TPM2_SE_POLICY = 0x01,
- TPM2_SE_TRIAL = 0x02,
-};
-
/* if you add a new hash to this, increment TPM_MAX_HASHES below */
enum tpm_algorithms {
TPM_ALG_ERROR = 0x0000,
@@ -65,11 +59,6 @@ enum tpm_algorithms {
*/
#define TPM_MAX_HASHES 5
-enum tpm2_curves {
- TPM2_ECC_NONE = 0x0000,
- TPM2_ECC_NIST_P256 = 0x0003,
-};
-
struct tpm_digest {
u16 alg_id;
u8 digest[TPM2_MAX_DIGEST_SIZE];
@@ -222,122 +211,11 @@ struct tpm_chip {
#define TPM_HEADER_SIZE 10
-enum tpm2_const {
- TPM2_PLATFORM_PCR = 24,
- TPM2_PCR_SELECT_MIN = ((TPM2_PLATFORM_PCR + 7) / 8),
-};
-
-enum tpm2_timeouts {
- TPM2_TIMEOUT_A = 750,
- TPM2_TIMEOUT_B = 4000,
- TPM2_TIMEOUT_C = 200,
- TPM2_TIMEOUT_D = 30,
-};
-
-enum tpm2_durations {
- TPM2_DURATION_SHORT = 20,
- TPM2_DURATION_LONG = 2000,
- TPM2_DURATION_DEFAULT = 120000,
-};
-
-enum tpm2_structures {
- TPM2_ST_NO_SESSIONS = 0x8001,
- TPM2_ST_SESSIONS = 0x8002,
- TPM2_ST_CREATION = 0x8021,
-};
-
-/* Indicates from what layer of the software stack the error comes from */
-#define TSS2_RC_LAYER_SHIFT 16
-#define TSS2_RESMGR_TPM_RC_LAYER (11 << TSS2_RC_LAYER_SHIFT)
-
-enum tpm2_return_codes {
- TPM2_RC_SUCCESS = 0x0000,
- TPM2_RC_HASH = 0x0083, /* RC_FMT1 */
- TPM2_RC_HANDLE = 0x008B,
- TPM2_RC_INTEGRITY = 0x009F,
- TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */
- TPM2_RC_FAILURE = 0x0101,
- TPM2_RC_DISABLED = 0x0120,
- TPM2_RC_UPGRADE = 0x012D,
- TPM2_RC_COMMAND_CODE = 0x0143,
- TPM2_RC_TESTING = 0x090A, /* RC_WARN */
- TPM2_RC_REFERENCE_H0 = 0x0910,
- TPM2_RC_RETRY = 0x0922,
- TPM2_RC_SESSION_MEMORY = 0x0903,
-};
-
-enum tpm2_command_codes {
- TPM2_CC_FIRST = 0x011F,
- TPM2_CC_HIERARCHY_CONTROL = 0x0121,
- TPM2_CC_HIERARCHY_CHANGE_AUTH = 0x0129,
- TPM2_CC_CREATE_PRIMARY = 0x0131,
- TPM2_CC_SEQUENCE_COMPLETE = 0x013E,
- TPM2_CC_SELF_TEST = 0x0143,
- TPM2_CC_STARTUP = 0x0144,
- TPM2_CC_SHUTDOWN = 0x0145,
- TPM2_CC_NV_READ = 0x014E,
- TPM2_CC_CREATE = 0x0153,
- TPM2_CC_LOAD = 0x0157,
- TPM2_CC_SEQUENCE_UPDATE = 0x015C,
- TPM2_CC_UNSEAL = 0x015E,
- TPM2_CC_CONTEXT_LOAD = 0x0161,
- TPM2_CC_CONTEXT_SAVE = 0x0162,
- TPM2_CC_FLUSH_CONTEXT = 0x0165,
- TPM2_CC_READ_PUBLIC = 0x0173,
- TPM2_CC_START_AUTH_SESS = 0x0176,
- TPM2_CC_VERIFY_SIGNATURE = 0x0177,
- TPM2_CC_GET_CAPABILITY = 0x017A,
- TPM2_CC_GET_RANDOM = 0x017B,
- TPM2_CC_PCR_READ = 0x017E,
- TPM2_CC_PCR_EXTEND = 0x0182,
- TPM2_CC_EVENT_SEQUENCE_COMPLETE = 0x0185,
- TPM2_CC_HASH_SEQUENCE_START = 0x0186,
- TPM2_CC_CREATE_LOADED = 0x0191,
- TPM2_CC_LAST = 0x0193, /* Spec 1.36 */
-};
-
-enum tpm2_permanent_handles {
- TPM2_RH_NULL = 0x40000007,
- TPM2_RS_PW = 0x40000009,
-};
-
-/* Most Significant Octet for key types */
-enum tpm2_mso_type {
- TPM2_MSO_NVRAM = 0x01,
- TPM2_MSO_SESSION = 0x02,
- TPM2_MSO_POLICY = 0x03,
- TPM2_MSO_PERMANENT = 0x40,
- TPM2_MSO_VOLATILE = 0x80,
- TPM2_MSO_PERSISTENT = 0x81,
-};
-
static inline enum tpm2_mso_type tpm2_handle_mso(u32 handle)
{
return handle >> 24;
}
-enum tpm2_capabilities {
- TPM2_CAP_HANDLES = 1,
- TPM2_CAP_COMMANDS = 2,
- TPM2_CAP_PCRS = 5,
- TPM2_CAP_TPM_PROPERTIES = 6,
-};
-
-enum tpm2_properties {
- TPM_PT_TOTAL_COMMANDS = 0x0129,
-};
-
-enum tpm2_startup_types {
- TPM2_SU_CLEAR = 0x0000,
- TPM2_SU_STATE = 0x0001,
-};
-
-enum tpm2_cc_attrs {
- TPM2_CC_ATTR_CHANDLES = 25,
- TPM2_CC_ATTR_RHANDLE = 28,
- TPM2_CC_ATTR_VENDOR = 29,
-};
-
#define TPM_VID_INTEL 0x8086
#define TPM_VID_WINBOND 0x1050
#define TPM_VID_STM 0x104A
@@ -389,29 +267,6 @@ struct tpm_buf {
u8 handles;
};
-enum tpm2_object_attributes {
- TPM2_OA_FIXED_TPM = BIT(1),
- TPM2_OA_ST_CLEAR = BIT(2),
- TPM2_OA_FIXED_PARENT = BIT(4),
- TPM2_OA_SENSITIVE_DATA_ORIGIN = BIT(5),
- TPM2_OA_USER_WITH_AUTH = BIT(6),
- TPM2_OA_ADMIN_WITH_POLICY = BIT(7),
- TPM2_OA_NO_DA = BIT(10),
- TPM2_OA_ENCRYPTED_DUPLICATION = BIT(11),
- TPM2_OA_RESTRICTED = BIT(16),
- TPM2_OA_DECRYPT = BIT(17),
- TPM2_OA_SIGN = BIT(18),
-};
-
-enum tpm2_session_attributes {
- TPM2_SA_CONTINUE_SESSION = BIT(0),
- TPM2_SA_AUDIT_EXCLUSIVE = BIT(1),
- TPM2_SA_AUDIT_RESET = BIT(3),
- TPM2_SA_DECRYPT = BIT(5),
- TPM2_SA_ENCRYPT = BIT(6),
- TPM2_SA_AUDIT = BIT(7),
-};
-
struct tpm2_hash {
unsigned int crypto_id;
unsigned int tpm_id;
diff --git a/include/linux/tpm_command.h b/include/linux/tpm_command.h
index 20b634591fb1..ee76fcd5ecef 100644
--- a/include/linux/tpm_command.h
+++ b/include/linux/tpm_command.h
@@ -158,4 +158,277 @@ struct tpm1_get_random_out {
#define TPM_NONCE_SIZE 20
#define TPM_ST_CLEAR 1
+/************************************************/
+/* TPM 2 Family Chips */
+/************************************************/
+
+/*
+ * TPM 2.0 Library
+ * https://trustedcomputinggroup.org/resource/tpm-library-specification/
+ */
+
+/* TPM2 specific constants. */
+#define TPM2_SPACE_BUFFER_SIZE 16384 /* 16 kB */
+
+enum tpm2_session_types {
+ TPM2_SE_HMAC = 0x00,
+ TPM2_SE_POLICY = 0x01,
+ TPM2_SE_TRIAL = 0x02,
+};
+
+enum tpm2_timeouts {
+ TPM2_TIMEOUT_A = 750,
+ TPM2_TIMEOUT_B = 4000,
+ TPM2_TIMEOUT_C = 200,
+ TPM2_TIMEOUT_D = 30,
+ TPM2_DURATION_SHORT = 20,
+ TPM2_DURATION_MEDIUM = 750,
+ TPM2_DURATION_LONG = 2000,
+ TPM2_DURATION_LONG_LONG = 300000,
+ TPM2_DURATION_DEFAULT = 120000,
+};
+
+enum tpm2_structures {
+ TPM2_ST_NO_SESSIONS = 0x8001,
+ TPM2_ST_SESSIONS = 0x8002,
+ TPM2_ST_CREATION = 0x8021,
+};
+
+/* Indicates from what layer of the software stack the error comes from */
+#define TSS2_RC_LAYER_SHIFT 16
+#define TSS2_RESMGR_TPM_RC_LAYER (11 << TSS2_RC_LAYER_SHIFT)
+
+enum tpm2_return_codes {
+ TPM2_RC_SUCCESS = 0x0000,
+ TPM2_RC_HASH = 0x0083, /* RC_FMT1 */
+ TPM2_RC_HANDLE = 0x008B,
+ TPM2_RC_INTEGRITY = 0x009F,
+ TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */
+ TPM2_RC_FAILURE = 0x0101,
+ TPM2_RC_DISABLED = 0x0120,
+ TPM2_RC_UPGRADE = 0x012D,
+ TPM2_RC_COMMAND_CODE = 0x0143,
+ TPM2_RC_TESTING = 0x090A, /* RC_WARN */
+ TPM2_RC_REFERENCE_H0 = 0x0910,
+ TPM2_RC_RETRY = 0x0922,
+ TPM2_RC_SESSION_MEMORY = 0x0903,
+};
+
+enum tpm2_command_codes {
+ TPM2_CC_FIRST = 0x011F,
+ TPM2_CC_HIERARCHY_CONTROL = 0x0121,
+ TPM2_CC_HIERARCHY_CHANGE_AUTH = 0x0129,
+ TPM2_CC_CREATE_PRIMARY = 0x0131,
+ TPM2_CC_SEQUENCE_COMPLETE = 0x013E,
+ TPM2_CC_SELF_TEST = 0x0143,
+ TPM2_CC_STARTUP = 0x0144,
+ TPM2_CC_SHUTDOWN = 0x0145,
+ TPM2_CC_NV_READ = 0x014E,
+ TPM2_CC_CREATE = 0x0153,
+ TPM2_CC_LOAD = 0x0157,
+ TPM2_CC_SEQUENCE_UPDATE = 0x015C,
+ TPM2_CC_UNSEAL = 0x015E,
+ TPM2_CC_CONTEXT_LOAD = 0x0161,
+ TPM2_CC_CONTEXT_SAVE = 0x0162,
+ TPM2_CC_FLUSH_CONTEXT = 0x0165,
+ TPM2_CC_READ_PUBLIC = 0x0173,
+ TPM2_CC_START_AUTH_SESS = 0x0176,
+ TPM2_CC_VERIFY_SIGNATURE = 0x0177,
+ TPM2_CC_GET_CAPABILITY = 0x017A,
+ TPM2_CC_GET_RANDOM = 0x017B,
+ TPM2_CC_PCR_READ = 0x017E,
+ TPM2_CC_PCR_EXTEND = 0x0182,
+ TPM2_CC_EVENT_SEQUENCE_COMPLETE = 0x0185,
+ TPM2_CC_HASH_SEQUENCE_START = 0x0186,
+ TPM2_CC_CREATE_LOADED = 0x0191,
+ TPM2_CC_LAST = 0x0193, /* Spec 1.36 */
+};
+
+enum tpm2_capabilities {
+ TPM2_CAP_HANDLES = 1,
+ TPM2_CAP_COMMANDS = 2,
+ TPM2_CAP_PCRS = 5,
+ TPM2_CAP_TPM_PROPERTIES = 6,
+};
+
+enum tpm2_properties {
+ TPM_PT_TOTAL_COMMANDS = 0x0129,
+};
+
+enum tpm2_startup_types {
+ TPM2_SU_CLEAR = 0x0000,
+ TPM2_SU_STATE = 0x0001,
+};
+
+enum tpm2_cc_attrs {
+ TPM2_CC_ATTR_CHANDLES = 25,
+ TPM2_CC_ATTR_RHANDLE = 28,
+ TPM2_CC_ATTR_VENDOR = 29,
+};
+
+enum tpm2_permanent_handles {
+ TPM2_RH_NULL = 0x40000007,
+ TPM2_RS_PW = 0x40000009,
+};
+
+/* Most Significant Octet for key types */
+enum tpm2_mso_type {
+ TPM2_MSO_NVRAM = 0x01,
+ TPM2_MSO_SESSION = 0x02,
+ TPM2_MSO_POLICY = 0x03,
+ TPM2_MSO_PERMANENT = 0x40,
+ TPM2_MSO_VOLATILE = 0x80,
+ TPM2_MSO_PERSISTENT = 0x81,
+};
+
+enum tpm2_curves {
+ TPM2_ECC_NONE = 0x0000,
+ TPM2_ECC_NIST_P256 = 0x0003,
+};
+
+enum tpm2_object_attributes {
+ TPM2_OA_FIXED_TPM = BIT(1),
+ TPM2_OA_ST_CLEAR = BIT(2),
+ TPM2_OA_FIXED_PARENT = BIT(4),
+ TPM2_OA_SENSITIVE_DATA_ORIGIN = BIT(5),
+ TPM2_OA_USER_WITH_AUTH = BIT(6),
+ TPM2_OA_ADMIN_WITH_POLICY = BIT(7),
+ TPM2_OA_NO_DA = BIT(10),
+ TPM2_OA_ENCRYPTED_DUPLICATION = BIT(11),
+ TPM2_OA_RESTRICTED = BIT(16),
+ TPM2_OA_DECRYPT = BIT(17),
+ TPM2_OA_SIGN = BIT(18),
+};
+
+enum tpm2_session_attributes {
+ TPM2_SA_CONTINUE_SESSION = BIT(0),
+ TPM2_SA_AUDIT_EXCLUSIVE = BIT(1),
+ TPM2_SA_AUDIT_RESET = BIT(3),
+ TPM2_SA_DECRYPT = BIT(5),
+ TPM2_SA_ENCRYPT = BIT(6),
+ TPM2_SA_AUDIT = BIT(7),
+};
+
+enum tpm2_pcr_select {
+ TPM2_PLATFORM_PCR = 24,
+ TPM2_PCR_SELECT_MIN = ((TPM2_PLATFORM_PCR + 7) / 8),
+};
+
+enum tpm2_handle_types {
+ TPM2_HT_HMAC_SESSION = 0x02000000,
+ TPM2_HT_POLICY_SESSION = 0x03000000,
+ TPM2_HT_TRANSIENT = 0x80000000,
+};
+
+enum tpm2_pt_props {
+ TPM2_PT_NONE = 0x00000000,
+ TPM2_PT_GROUP = 0x00000100,
+ TPM2_PT_FIXED = TPM2_PT_GROUP * 1,
+ TPM2_PT_FAMILY_INDICATOR = TPM2_PT_FIXED + 0,
+ TPM2_PT_LEVEL = TPM2_PT_FIXED + 1,
+ TPM2_PT_REVISION = TPM2_PT_FIXED + 2,
+ TPM2_PT_DAY_OF_YEAR = TPM2_PT_FIXED + 3,
+ TPM2_PT_YEAR = TPM2_PT_FIXED + 4,
+ TPM2_PT_MANUFACTURER = TPM2_PT_FIXED + 5,
+ TPM2_PT_VENDOR_STRING_1 = TPM2_PT_FIXED + 6,
+ TPM2_PT_VENDOR_STRING_2 = TPM2_PT_FIXED + 7,
+ TPM2_PT_VENDOR_STRING_3 = TPM2_PT_FIXED + 8,
+ TPM2_PT_VENDOR_STRING_4 = TPM2_PT_FIXED + 9,
+ TPM2_PT_VENDOR_TPM_TYPE = TPM2_PT_FIXED + 10,
+ TPM2_PT_FIRMWARE_VERSION_1 = TPM2_PT_FIXED + 11,
+ TPM2_PT_FIRMWARE_VERSION_2 = TPM2_PT_FIXED + 12,
+ TPM2_PT_INPUT_BUFFER = TPM2_PT_FIXED + 13,
+ TPM2_PT_HR_TRANSIENT_MIN = TPM2_PT_FIXED + 14,
+ TPM2_PT_HR_PERSISTENT_MIN = TPM2_PT_FIXED + 15,
+ TPM2_PT_HR_LOADED_MIN = TPM2_PT_FIXED + 16,
+ TPM2_PT_ACTIVE_SESSIONS_MAX = TPM2_PT_FIXED + 17,
+ TPM2_PT_PCR_COUNT = TPM2_PT_FIXED + 18,
+ TPM2_PT_PCR_SELECT_MIN = TPM2_PT_FIXED + 19,
+ TPM2_PT_CONTEXT_GAP_MAX = TPM2_PT_FIXED + 20,
+ TPM2_PT_NV_COUNTERS_MAX = TPM2_PT_FIXED + 22,
+ TPM2_PT_NV_INDEX_MAX = TPM2_PT_FIXED + 23,
+ TPM2_PT_MEMORY = TPM2_PT_FIXED + 24,
+ TPM2_PT_CLOCK_UPDATE = TPM2_PT_FIXED + 25,
+ TPM2_PT_CONTEXT_HASH = TPM2_PT_FIXED + 26,
+ TPM2_PT_CONTEXT_SYM = TPM2_PT_FIXED + 27,
+ TPM2_PT_CONTEXT_SYM_SIZE = TPM2_PT_FIXED + 28,
+ TPM2_PT_ORDERLY_COUNT = TPM2_PT_FIXED + 29,
+ TPM2_PT_MAX_COMMAND_SIZE = TPM2_PT_FIXED + 30,
+ TPM2_PT_MAX_RESPONSE_SIZE = TPM2_PT_FIXED + 31,
+ TPM2_PT_MAX_DIGEST = TPM2_PT_FIXED + 32,
+ TPM2_PT_MAX_OBJECT_CONTEXT = TPM2_PT_FIXED + 33,
+ TPM2_PT_MAX_SESSION_CONTEXT = TPM2_PT_FIXED + 34,
+ TPM2_PT_PS_FAMILY_INDICATOR = TPM2_PT_FIXED + 35,
+ TPM2_PT_PS_LEVEL = TPM2_PT_FIXED + 36,
+ TPM2_PT_PS_REVISION = TPM2_PT_FIXED + 37,
+ TPM2_PT_PS_DAY_OF_YEAR = TPM2_PT_FIXED + 38,
+ TPM2_PT_PS_YEAR = TPM2_PT_FIXED + 39,
+ TPM2_PT_SPLIT_MAX = TPM2_PT_FIXED + 40,
+ TPM2_PT_TOTAL_COMMANDS = TPM2_PT_FIXED + 41,
+ TPM2_PT_LIBRARY_COMMANDS = TPM2_PT_FIXED + 42,
+ TPM2_PT_VENDOR_COMMANDS = TPM2_PT_FIXED + 43,
+ TPM2_PT_NV_BUFFER_MAX = TPM2_PT_FIXED + 44,
+ TPM2_PT_MODES = TPM2_PT_FIXED + 45,
+ TPM2_PT_MAX_CAP_BUFFER = TPM2_PT_FIXED + 46,
+ TPM2_PT_VAR = TPM2_PT_GROUP * 2,
+ TPM2_PT_PERMANENT = TPM2_PT_VAR + 0,
+ TPM2_PT_STARTUP_CLEAR = TPM2_PT_VAR + 1,
+ TPM2_PT_HR_NV_INDEX = TPM2_PT_VAR + 2,
+ TPM2_PT_HR_LOADED = TPM2_PT_VAR + 3,
+ TPM2_PT_HR_LOADED_AVAIL = TPM2_PT_VAR + 4,
+ TPM2_PT_HR_ACTIVE = TPM2_PT_VAR + 5,
+ TPM2_PT_HR_ACTIVE_AVAIL = TPM2_PT_VAR + 6,
+ TPM2_PT_HR_TRANSIENT_AVAIL = TPM2_PT_VAR + 7,
+ TPM2_PT_HR_PERSISTENT = TPM2_PT_VAR + 8,
+ TPM2_PT_HR_PERSISTENT_AVAIL = TPM2_PT_VAR + 9,
+ TPM2_PT_NV_COUNTERS = TPM2_PT_VAR + 10,
+ TPM2_PT_NV_COUNTERS_AVAIL = TPM2_PT_VAR + 11,
+ TPM2_PT_ALGORITHM_SET = TPM2_PT_VAR + 12,
+ TPM2_PT_LOADED_CURVES = TPM2_PT_VAR + 13,
+ TPM2_PT_LOCKOUT_COUNTER = TPM2_PT_VAR + 14,
+ TPM2_PT_MAX_AUTH_FAIL = TPM2_PT_VAR + 15,
+ TPM2_PT_LOCKOUT_INTERVAL = TPM2_PT_VAR + 16,
+ TPM2_PT_LOCKOUT_RECOVERY = TPM2_PT_VAR + 17,
+ TPM2_PT_NV_WRITE_RECOVERY = TPM2_PT_VAR + 18,
+ TPM2_PT_AUDIT_COUNTER_0 = TPM2_PT_VAR + 19,
+ TPM2_PT_AUDIT_COUNTER_1 = TPM2_PT_VAR + 20,
+};
+
+struct tpm2_pcr_read_out {
+ __be32 update_cnt;
+ __be32 pcr_selects_cnt;
+ __be16 hash_alg;
+ u8 pcr_select_size;
+ u8 pcr_select[TPM2_PCR_SELECT_MIN];
+ __be32 digests_cnt;
+ __be16 digest_size;
+ u8 digest[];
+} __packed;
+
+struct tpm2_get_random_out {
+ __be16 size;
+ u8 buffer[TPM_MAX_RNG_DATA];
+} __packed;
+
+struct tpm2_get_cap_out {
+ u8 more_data;
+ __be32 subcap_id;
+ __be32 property_cnt;
+ __be32 property_id;
+ __be32 value;
+} __packed;
+
+struct tpm2_pcr_selection {
+ __be16 hash_alg;
+ u8 size_of_select;
+ u8 pcr_select[3];
+} __packed;
+
+struct tpm2_context {
+ __be64 sequence;
+ __be32 saved_handle;
+ __be32 hierarchy;
+ __be16 blob_size;
+} __packed;
+
#endif
--
2.47.3
^ permalink raw reply related
* [PATCH 2/4] tpm: Move TPM1 specific definitions to the command header
From: Alec Brown @ 2026-03-17 16:03 UTC (permalink / raw)
To: linux-kernel, linux-integrity, jarkko
Cc: peterhuewe, jarkko.sakkinen, jgg, ross.philipson, dpsmith,
daniel.kiper, kanth.ghatraju, trenchboot-devel, ardb,
alec.r.brown
In-Reply-To: <20260317160613.2899129-1-alec.r.brown@oracle.com>
From: Ross Philipson <ross.philipson@oracle.com>
From: Ross Philipson <ross.philipson@oracle.com>
Gather all the TPM1 definitions and structures in the internal header
file drivers/char/tpm/tpm.h into the command header. In addition, bring
in the single RNG structure from tpm-interface.c.
The definitions moved to these files correspond to the TCG specification
for TPM 1 family:
TPM 1.2 Main Specification
- https://trustedcomputinggroup.org/resource/tpm-main-specification/
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
---
drivers/char/tpm/tpm.h | 102 --------------------------------
drivers/char/tpm/tpm1-cmd.c | 5 --
include/linux/tpm_command.h | 115 ++++++++++++++++++++++++++++++++++++
3 files changed, 115 insertions(+), 107 deletions(-)
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 02c07fef41ba..1a9a46a921fe 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -51,105 +51,9 @@ enum tpm_addr {
TPM_ADDR = 0x4E,
};
-#define TPM_WARN_RETRY 0x800
-#define TPM_WARN_DOING_SELFTEST 0x802
-#define TPM_ERR_DEACTIVATED 0x6
-#define TPM_ERR_DISABLED 0x7
-#define TPM_ERR_FAILEDSELFTEST 0x1C
-#define TPM_ERR_INVALID_POSTINIT 38
-
-#define TPM_TAG_RQU_COMMAND 193
-
/* TPM2 specific constants. */
#define TPM2_SPACE_BUFFER_SIZE 16384 /* 16 kB */
-struct stclear_flags_t {
- __be16 tag;
- u8 deactivated;
- u8 disableForceClear;
- u8 physicalPresence;
- u8 physicalPresenceLock;
- u8 bGlobalLock;
-} __packed;
-
-struct tpm1_version {
- u8 major;
- u8 minor;
- u8 rev_major;
- u8 rev_minor;
-} __packed;
-
-struct tpm1_version2 {
- __be16 tag;
- struct tpm1_version version;
-} __packed;
-
-struct timeout_t {
- __be32 a;
- __be32 b;
- __be32 c;
- __be32 d;
-} __packed;
-
-struct duration_t {
- __be32 tpm_short;
- __be32 tpm_medium;
- __be32 tpm_long;
-} __packed;
-
-struct permanent_flags_t {
- __be16 tag;
- u8 disable;
- u8 ownership;
- u8 deactivated;
- u8 readPubek;
- u8 disableOwnerClear;
- u8 allowMaintenance;
- u8 physicalPresenceLifetimeLock;
- u8 physicalPresenceHWEnable;
- u8 physicalPresenceCMDEnable;
- u8 CEKPUsed;
- u8 TPMpost;
- u8 TPMpostLock;
- u8 FIPS;
- u8 operator;
- u8 enableRevokeEK;
- u8 nvLocked;
- u8 readSRKPub;
- u8 tpmEstablished;
- u8 maintenanceDone;
- u8 disableFullDALogicInfo;
-} __packed;
-
-typedef union {
- struct permanent_flags_t perm_flags;
- struct stclear_flags_t stclear_flags;
- __u8 owned;
- __be32 num_pcrs;
- struct tpm1_version version1;
- struct tpm1_version2 version2;
- __be32 manufacturer_id;
- struct timeout_t timeout;
- struct duration_t duration;
-} cap_t;
-
-enum tpm_capabilities {
- TPM_CAP_FLAG = 4,
- TPM_CAP_PROP = 5,
- TPM_CAP_VERSION_1_1 = 0x06,
- TPM_CAP_VERSION_1_2 = 0x1A,
-};
-
-enum tpm_sub_capabilities {
- TPM_CAP_PROP_PCR = 0x101,
- TPM_CAP_PROP_MANUFACTURER = 0x103,
- TPM_CAP_FLAG_PERM = 0x108,
- TPM_CAP_FLAG_VOL = 0x109,
- TPM_CAP_PROP_OWNER = 0x111,
- TPM_CAP_PROP_TIS_TIMEOUT = 0x115,
- TPM_CAP_PROP_TIS_DURATION = 0x120,
-};
-
enum tpm2_pt_props {
TPM2_PT_NONE = 0x00000000,
TPM2_PT_GROUP = 0x00000100,
@@ -224,12 +128,6 @@ enum tpm2_pt_props {
TPM2_PT_AUDIT_COUNTER_1 = TPM2_PT_VAR + 20,
};
-/* 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
- * bytes, but 128 is still a relatively large number of random bytes and
- * anything much bigger causes users of struct tpm_cmd_t to start getting
- * compiler warnings about stack frame size. */
-#define TPM_MAX_RNG_DATA 128
-
extern const struct class tpm_class;
extern const struct class tpmrm_class;
extern dev_t tpm_devt;
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index 664ca1fff2e8..96f189b5fd6f 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -504,11 +504,6 @@ ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
}
EXPORT_SYMBOL_GPL(tpm1_getcap);
-struct tpm1_get_random_out {
- __be32 rng_data_len;
- u8 rng_data[TPM_MAX_RNG_DATA];
-} __packed;
-
/**
* tpm1_get_random() - get random bytes from the TPM's RNG
* @chip: a &struct tpm_chip instance
diff --git a/include/linux/tpm_command.h b/include/linux/tpm_command.h
index 9a8991b8801d..20b634591fb1 100644
--- a/include/linux/tpm_command.h
+++ b/include/linux/tpm_command.h
@@ -38,6 +38,121 @@ enum tpm_command_ordinals {
TPM_ORD_UNSEAL = 24,
};
+enum tpm_capabilities {
+ TPM_CAP_FLAG = 4,
+ TPM_CAP_PROP = 5,
+ TPM_CAP_VERSION_1_1 = 0x06,
+ TPM_CAP_VERSION_1_2 = 0x1A,
+};
+
+enum tpm_sub_capabilities {
+ TPM_CAP_PROP_PCR = 0x101,
+ TPM_CAP_PROP_MANUFACTURER = 0x103,
+ TPM_CAP_FLAG_PERM = 0x108,
+ TPM_CAP_FLAG_VOL = 0x109,
+ TPM_CAP_PROP_OWNER = 0x111,
+ TPM_CAP_PROP_TIS_TIMEOUT = 0x115,
+ TPM_CAP_PROP_TIS_DURATION = 0x120,
+};
+
+/* Return Codes */
+enum tpm_return_codes {
+ TPM_BASE_MASK = 0,
+ TPM_NON_FATAL_MASK = 0x00000800,
+ TPM_SUCCESS = TPM_BASE_MASK + 0,
+ TPM_ERR_DEACTIVATED = TPM_BASE_MASK + 6,
+ TPM_ERR_DISABLED = TPM_BASE_MASK + 7,
+ TPM_ERR_FAIL = TPM_BASE_MASK + 9,
+ TPM_ERR_FAILEDSELFTEST = TPM_BASE_MASK + 28,
+ TPM_ERR_INVALID_POSTINIT = TPM_BASE_MASK + 38,
+ TPM_ERR_INVALID_FAMILY = TPM_BASE_MASK + 55,
+ TPM_WARN_RETRY = TPM_BASE_MASK + TPM_NON_FATAL_MASK + 0,
+ TPM_WARN_DOING_SELFTEST = TPM_BASE_MASK + TPM_NON_FATAL_MASK + 2,
+};
+
+struct stclear_flags_t {
+ __be16 tag;
+ u8 deactivated;
+ u8 disableForceClear;
+ u8 physicalPresence;
+ u8 physicalPresenceLock;
+ u8 bGlobalLock;
+} __packed;
+
+struct tpm1_version {
+ u8 major;
+ u8 minor;
+ u8 rev_major;
+ u8 rev_minor;
+} __packed;
+
+struct tpm1_version2 {
+ __be16 tag;
+ struct tpm1_version version;
+} __packed;
+
+struct timeout_t {
+ __be32 a;
+ __be32 b;
+ __be32 c;
+ __be32 d;
+} __packed;
+
+struct duration_t {
+ __be32 tpm_short;
+ __be32 tpm_medium;
+ __be32 tpm_long;
+} __packed;
+
+struct permanent_flags_t {
+ __be16 tag;
+ u8 disable;
+ u8 ownership;
+ u8 deactivated;
+ u8 readPubek;
+ u8 disableOwnerClear;
+ u8 allowMaintenance;
+ u8 physicalPresenceLifetimeLock;
+ u8 physicalPresenceHWEnable;
+ u8 physicalPresenceCMDEnable;
+ u8 CEKPUsed;
+ u8 TPMpost;
+ u8 TPMpostLock;
+ u8 FIPS;
+ u8 operator;
+ u8 enableRevokeEK;
+ u8 nvLocked;
+ u8 readSRKPub;
+ u8 tpmEstablished;
+ u8 maintenanceDone;
+ u8 disableFullDALogicInfo;
+} __packed;
+
+typedef union {
+ struct permanent_flags_t perm_flags;
+ struct stclear_flags_t stclear_flags;
+ __u8 owned;
+ __be32 num_pcrs;
+ struct tpm1_version version1;
+ struct tpm1_version2 version2;
+ __be32 manufacturer_id;
+ struct timeout_t timeout;
+ struct duration_t duration;
+} cap_t;
+
+/*
+ * 128 bytes is an arbitrary cap. This could be as large as TPM_BUFSIZE - 18
+ * bytes, but 128 is still a relatively large number of random bytes and
+ * anything much bigger causes users of struct tpm_cmd_t to start getting
+ * compiler warnings about stack frame size.
+ */
+#define TPM_MAX_RNG_DATA 128
+
+struct tpm1_get_random_out {
+ __be32 rng_data_len;
+ u8 rng_data[TPM_MAX_RNG_DATA];
+} __packed;
+
/* Other constants */
#define SRKHANDLE 0x40000000
#define TPM_NONCE_SIZE 20
--
2.47.3
^ permalink raw reply related
* [PATCH 1/4] tpm: Initial step to reorganize TPM public headers
From: Alec Brown @ 2026-03-17 16:03 UTC (permalink / raw)
To: linux-kernel, linux-integrity, jarkko
Cc: peterhuewe, jarkko.sakkinen, jgg, ross.philipson, dpsmith,
daniel.kiper, kanth.ghatraju, trenchboot-devel, ardb,
alec.r.brown
In-Reply-To: <20260317160613.2899129-1-alec.r.brown@oracle.com>
From: Ross Philipson <ross.philipson@oracle.com>
From: Ross Philipson <ross.philipson@oracle.com>
Consolidate TPM1 constants in tpm_command.h and remove duplicate
constants from tpm1-cmd.c.
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
---
drivers/char/tpm/tpm-buf.c | 1 -
drivers/char/tpm/tpm1-cmd.c | 14 +-------
include/keys/trusted_tpm.h | 1 -
include/linux/tpm.h | 2 ++
include/linux/tpm_command.h | 43 ++++++++++++++++-------
security/keys/trusted-keys/trusted_tpm1.c | 1 -
security/keys/trusted-keys/trusted_tpm2.c | 1 -
7 files changed, 33 insertions(+), 30 deletions(-)
diff --git a/drivers/char/tpm/tpm-buf.c b/drivers/char/tpm/tpm-buf.c
index dc882fc9fa9e..4c4f450630df 100644
--- a/drivers/char/tpm/tpm-buf.c
+++ b/drivers/char/tpm/tpm-buf.c
@@ -3,7 +3,6 @@
* Handling of TPM command and other buffers.
*/
-#include <linux/tpm_command.h>
#include <linux/module.h>
#include <linux/tpm.h>
diff --git a/drivers/char/tpm/tpm1-cmd.c b/drivers/char/tpm/tpm1-cmd.c
index b49a790f1bd5..664ca1fff2e8 100644
--- a/drivers/char/tpm/tpm1-cmd.c
+++ b/drivers/char/tpm/tpm1-cmd.c
@@ -22,8 +22,6 @@
#include "tpm.h"
-#define TPM_MAX_ORDINAL 243
-
/*
* Array with one entry per ordinal defining the maximum amount
* of time the chip could take to return the result. The ordinal
@@ -308,9 +306,6 @@ unsigned long tpm1_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
return duration;
}
-#define TPM_ORD_STARTUP 153
-#define TPM_ST_CLEAR 1
-
/**
* tpm1_startup() - turn on the TPM
* @chip: TPM chip to use
@@ -459,7 +454,6 @@ int tpm1_get_timeouts(struct tpm_chip *chip)
return 0;
}
-#define TPM_ORD_PCR_EXTEND 20
int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash,
const char *log_msg)
{
@@ -478,7 +472,6 @@ int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash,
return rc;
}
-#define TPM_ORD_GET_CAP 101
ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
const char *desc, size_t min_cap_length)
{
@@ -511,7 +504,6 @@ ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
}
EXPORT_SYMBOL_GPL(tpm1_getcap);
-#define TPM_ORD_GET_RANDOM 70
struct tpm1_get_random_out {
__be32 rng_data_len;
u8 rng_data[TPM_MAX_RNG_DATA];
@@ -580,13 +572,12 @@ int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
return rc;
}
-#define TPM_ORD_PCRREAD 21
int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
{
struct tpm_buf buf;
int rc;
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCRREAD);
+ rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCR_READ);
if (rc)
return rc;
@@ -609,7 +600,6 @@ int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
return rc;
}
-#define TPM_ORD_CONTINUE_SELFTEST 83
/**
* tpm1_continue_selftest() - run TPM's selftest
* @chip: TPM chip to use
@@ -726,8 +716,6 @@ int tpm1_auto_startup(struct tpm_chip *chip)
return rc;
}
-#define TPM_ORD_SAVESTATE 152
-
/**
* tpm1_pm_suspend() - pm suspend handler
* @chip: TPM chip to use.
diff --git a/include/keys/trusted_tpm.h b/include/keys/trusted_tpm.h
index 0fadc6a4f166..3a0fa3bc8454 100644
--- a/include/keys/trusted_tpm.h
+++ b/include/keys/trusted_tpm.h
@@ -3,7 +3,6 @@
#define __TRUSTED_TPM_H
#include <keys/trusted-type.h>
-#include <linux/tpm_command.h>
extern struct trusted_key_ops trusted_key_tpm_ops;
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 202da079d500..18dcf0ef46f6 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -25,6 +25,8 @@
#include <crypto/hash_info.h>
#include <crypto/aes.h>
+#include "tpm_command.h"
+
#define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */
#define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
diff --git a/include/linux/tpm_command.h b/include/linux/tpm_command.h
index f5c03e9c3913..9a8991b8801d 100644
--- a/include/linux/tpm_command.h
+++ b/include/linux/tpm_command.h
@@ -2,28 +2,45 @@
#ifndef __LINUX_TPM_COMMAND_H__
#define __LINUX_TPM_COMMAND_H__
+/************************************************/
+/* TPM 1 Family Chips */
+/************************************************/
+
/*
- * TPM Command constants from specifications at
- * http://www.trustedcomputinggroup.org
+ * TPM 1.2 Main Specification
+ * https://trustedcomputinggroup.org/resource/tpm-main-specification/
*/
+#define TPM_MAX_ORDINAL 243
+
/* Command TAGS */
-#define TPM_TAG_RQU_COMMAND 193
-#define TPM_TAG_RQU_AUTH1_COMMAND 194
-#define TPM_TAG_RQU_AUTH2_COMMAND 195
-#define TPM_TAG_RSP_COMMAND 196
-#define TPM_TAG_RSP_AUTH1_COMMAND 197
-#define TPM_TAG_RSP_AUTH2_COMMAND 198
+enum tpm_command_tags {
+ TPM_TAG_RQU_COMMAND = 193,
+ TPM_TAG_RQU_AUTH1_COMMAND = 194,
+ TPM_TAG_RQU_AUTH2_COMMAND = 195,
+ TPM_TAG_RSP_COMMAND = 196,
+ TPM_TAG_RSP_AUTH1_COMMAND = 197,
+ TPM_TAG_RSP_AUTH2_COMMAND = 198,
+};
/* Command Ordinals */
-#define TPM_ORD_GETRANDOM 70
-#define TPM_ORD_OSAP 11
-#define TPM_ORD_OIAP 10
-#define TPM_ORD_SEAL 23
-#define TPM_ORD_UNSEAL 24
+enum tpm_command_ordinals {
+ TPM_ORD_CONTINUE_SELFTEST = 83,
+ TPM_ORD_GET_CAP = 101,
+ TPM_ORD_GET_RANDOM = 70,
+ TPM_ORD_PCR_EXTEND = 20,
+ TPM_ORD_PCR_READ = 21,
+ TPM_ORD_OSAP = 11,
+ TPM_ORD_OIAP = 10,
+ TPM_ORD_SAVESTATE = 152,
+ TPM_ORD_SEAL = 23,
+ TPM_ORD_STARTUP = 153,
+ TPM_ORD_UNSEAL = 24,
+};
/* Other constants */
#define SRKHANDLE 0x40000000
#define TPM_NONCE_SIZE 20
+#define TPM_ST_CLEAR 1
#endif
diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c
index 636acb66a4f6..10f79a8c2d35 100644
--- a/security/keys/trusted-keys/trusted_tpm1.c
+++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -17,7 +17,6 @@
#include <keys/trusted-type.h>
#include <linux/key-type.h>
#include <linux/tpm.h>
-#include <linux/tpm_command.h>
#include <keys/trusted_tpm.h>
diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c
index a7ea4a1c3bed..56eb8e20780a 100644
--- a/security/keys/trusted-keys/trusted_tpm2.c
+++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -9,7 +9,6 @@
#include <linux/string.h>
#include <linux/err.h>
#include <linux/tpm.h>
-#include <linux/tpm_command.h>
#include <keys/trusted-type.h>
#include <keys/trusted_tpm.h>
--
2.47.3
^ permalink raw reply related
* [PATCH 0/4] Reorganize TPM public headers
From: Alec Brown @ 2026-03-17 16:03 UTC (permalink / raw)
To: linux-kernel, linux-integrity, jarkko
Cc: peterhuewe, jarkko.sakkinen, jgg, ross.philipson, dpsmith,
daniel.kiper, kanth.ghatraju, trenchboot-devel, ardb,
alec.r.brown
This patch series reorganizes various TPM definitions into tpm_command.h and
groups them corresponding to the TCG specification for TPM1 and TPM2. The
purpose in reorganizing these definitions is to assist the TPM driver usability
in pre-boot environments. This series is related to Jarkko Sakkinen's work
streamlining TPM2 HMAC sessions but can be applied independently of his
patches.
Ross Philipson (4):
tpm: Initial step to reorganize TPM public headers
tpm: Move TPM1 specific definitions to the command header
tpm: Move TPM2 specific definitions to the command header
tpm: Move TPM common base definitions to the command header
drivers/char/tpm/tpm-buf.c | 1 -
drivers/char/tpm/tpm.h | 179 ----------
drivers/char/tpm/tpm1-cmd.c | 19 +-
drivers/char/tpm/tpm2-cmd.c | 30 --
drivers/char/tpm/tpm2-space.c | 13 -
include/keys/trusted_tpm.h | 1 -
include/linux/tpm.h | 195 +----------
include/linux/tpm_command.h | 520 +++++++++++++++++++++++++++++-
security/keys/trusted-keys/trusted_tpm1.c | 1 -
security/keys/trusted-keys/trusted_tpm2.c | 1 -
10 files changed, 510 insertions(+), 450 deletions(-)
^ permalink raw reply
* [PATCH 4/4] tpm: Move TPM common base definitions to the command header
From: Alec Brown @ 2026-03-17 16:03 UTC (permalink / raw)
To: linux-kernel, linux-integrity, jarkko
Cc: peterhuewe, jarkko.sakkinen, jgg, ross.philipson, dpsmith,
daniel.kiper, kanth.ghatraju, trenchboot-devel, ardb,
alec.r.brown
In-Reply-To: <20260317160613.2899129-1-alec.r.brown@oracle.com>
From: Ross Philipson <ross.philipson@oracle.com>
From: Ross Philipson <ross.philipson@oracle.com>
These are top level definitions shared by both TPM 1 and 2
family chips. This includes core definitions like TPM localities,
common crypto algorithm IDs, and the base TPM command header.
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
---
include/linux/tpm.h | 50 +--------------------
include/linux/tpm_command.h | 89 +++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+), 49 deletions(-)
diff --git a/include/linux/tpm.h b/include/linux/tpm.h
index 92957452f7a7..a282b7045a24 100644
--- a/include/linux/tpm.h
+++ b/include/linux/tpm.h
@@ -27,49 +27,12 @@
#include "tpm_command.h"
-#define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */
-
-#define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
-#define TPM2_MAX_PCR_BANKS 8
-
struct tpm_chip;
struct trusted_key_payload;
struct trusted_key_options;
/* opaque structure, holds auth session parameters like the session key */
struct tpm2_auth;
-/* if you add a new hash to this, increment TPM_MAX_HASHES below */
-enum tpm_algorithms {
- TPM_ALG_ERROR = 0x0000,
- TPM_ALG_SHA1 = 0x0004,
- TPM_ALG_AES = 0x0006,
- TPM_ALG_KEYEDHASH = 0x0008,
- TPM_ALG_SHA256 = 0x000B,
- TPM_ALG_SHA384 = 0x000C,
- TPM_ALG_SHA512 = 0x000D,
- TPM_ALG_NULL = 0x0010,
- TPM_ALG_SM3_256 = 0x0012,
- TPM_ALG_ECC = 0x0023,
- TPM_ALG_CFB = 0x0043,
-};
-
-/*
- * maximum number of hashing algorithms a TPM can have. This is
- * basically a count of every hash in tpm_algorithms above
- */
-#define TPM_MAX_HASHES 5
-
-struct tpm_digest {
- u16 alg_id;
- u8 digest[TPM2_MAX_DIGEST_SIZE];
-} __packed;
-
-struct tpm_bank_info {
- u16 alg_id;
- u16 digest_size;
- u16 crypto_id;
-};
-
enum TPM_OPS_FLAGS {
TPM_OPS_AUTO_STARTUP = BIT(0),
};
@@ -127,7 +90,7 @@ struct tpm_chip_seqops {
const struct seq_operations *seqops;
};
-/* fixed define for the curve we use which is NIST_P256 */
+/* Fixed define for the curve we use which is NIST_P256 */
#define EC_PT_SZ 32
/*
@@ -209,8 +172,6 @@ struct tpm_chip {
#endif
};
-#define TPM_HEADER_SIZE 10
-
static inline enum tpm2_mso_type tpm2_handle_mso(u32 handle)
{
return handle >> 24;
@@ -239,15 +200,6 @@ enum tpm_chip_flags {
#define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
-struct tpm_header {
- __be16 tag;
- __be32 length;
- union {
- __be32 ordinal;
- __be32 return_code;
- };
-} __packed;
-
enum tpm_buf_flags {
/* the capacity exceeded: */
TPM_BUF_OVERFLOW = BIT(0),
diff --git a/include/linux/tpm_command.h b/include/linux/tpm_command.h
index ee76fcd5ecef..25a247254140 100644
--- a/include/linux/tpm_command.h
+++ b/include/linux/tpm_command.h
@@ -431,4 +431,93 @@ struct tpm2_context {
__be16 blob_size;
} __packed;
+/************************************************/
+/* TPM Common Defs */
+/************************************************/
+
+#define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */
+#define TPM_BUFSIZE 4096
+
+/*
+ * SHA-512 is, as of today, the largest digest in the TCG algorithm repository.
+ */
+#define TPM2_MAX_DIGEST_SIZE SHA512_DIGEST_SIZE
+
+/*
+ * A TPM name digest i.e., TPMT_HA, is a concatenation of TPM_ALG_ID of the
+ * name algorithm and hash of TPMT_PUBLIC.
+ */
+#define TPM2_MAX_NAME_SIZE (TPM2_MAX_DIGEST_SIZE + 2)
+
+/*
+ * Fixed define for the size of a name. This is actually HASHALG size
+ * plus 2, so 32 for SHA256
+ */
+#define TPM2_NULL_NAME_SIZE 34
+
+/*
+ * The maximum number of PCR banks.
+ */
+#define TPM2_MAX_PCR_BANKS 8
+
+/* If you add a new hash to this, increment TPM_MAX_HASHES below */
+enum tpm_algorithms {
+ TPM_ALG_ERROR = 0x0000,
+ TPM_ALG_SHA1 = 0x0004,
+ TPM_ALG_AES = 0x0006,
+ TPM_ALG_KEYEDHASH = 0x0008,
+ TPM_ALG_SHA256 = 0x000B,
+ TPM_ALG_SHA384 = 0x000C,
+ TPM_ALG_SHA512 = 0x000D,
+ TPM_ALG_NULL = 0x0010,
+ TPM_ALG_SM3_256 = 0x0012,
+ TPM_ALG_ECC = 0x0023,
+ TPM_ALG_CFB = 0x0043,
+};
+
+/*
+ * The locality (0 - 4) for a TPM, as defined in section 3.2 of the
+ * Client Platform Profile Specification.
+ */
+enum tpm_localities {
+ TPM_LOCALITY_0 = 0, /* Static RTM */
+ TPM_LOCALITY_1 = 1, /* Dynamic OS */
+ TPM_LOCALITY_2 = 2, /* DRTM Environment */
+ TPM_LOCALITY_3 = 3, /* Aux Components */
+ TPM_LOCALITY_4 = 4, /* CPU DRTM Establishment */
+ TPM_MAX_LOCALITY = TPM_LOCALITY_4
+};
+
+/*
+ * Structure to represent active PCR algorithm banks usable by the
+ * TPM chip.
+ */
+struct tpm_bank_info {
+ u16 alg_id;
+ u16 digest_size;
+ u16 crypto_id;
+};
+
+/*
+ * Maximum number of hashing algorithms a TPM can have. This is
+ * basically a count of every hash in tpm_algorithms above
+ */
+#define TPM_MAX_HASHES 5
+
+struct tpm_digest {
+ u16 alg_id;
+ u8 digest[TPM2_MAX_DIGEST_SIZE];
+} __packed;
+
+#define TPM_HEADER_SIZE 10
+
+struct tpm_header {
+ __be16 tag;
+ __be32 length;
+ union {
+ __be32 ordinal;
+ __be32 return_code;
+ };
+} __packed;
+
#endif
--
2.47.3
^ permalink raw reply related
* Re: [PATCH v3 0/2] vfs: follow-on fixes for i_ino widening
From: Christian Brauner @ 2026-03-17 14:39 UTC (permalink / raw)
To: Jeff Layton
Cc: Christian Brauner, David Laight, linux-nilfs, linux-kernel,
linux-integrity, linux-security-module, linux-fsdevel,
kernel test robot, Ryusuke Konishi, Viacheslav Dubeyko,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn
In-Reply-To: <20260316-iino-u64-v3-0-d1076b8f7a20@kernel.org>
On Mon, 16 Mar 2026 15:02:21 -0400, Jeff Layton wrote:
> Just some patches to fix follow-on issues reported after the
> inode->i_ino widening series. Christian, could you toss these
> onto the vfs-7.1.kino branch?
Applied to the vfs-7.1.kino branch of the vfs/vfs.git tree.
Patches in the vfs-7.1.kino branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs-7.1.kino
[1/2] EVM: add comment describing why ino field is still unsigned long
https://git.kernel.org/vfs/vfs/c/bef5b11087ce
[2/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
https://git.kernel.org/vfs/vfs/c/81359c146fba
^ permalink raw reply
* Re: [PATCH] ima: remove buggy support for asynchronous hashes
From: Dmitry Kasatkin @ 2026-03-17 14:13 UTC (permalink / raw)
To: Eric Biggers
Cc: Mimi Zohar, linux-integrity, Roberto Sassu, linux-crypto,
linux-kernel
In-Reply-To: <20260314182501.GA40504@quark>
On Sat, 14 Mar 2026 at 20:25, Eric Biggers <ebiggers@kernel.org> wrote:
>
> On Thu, Mar 12, 2026 at 07:29:05PM -0400, Mimi Zohar wrote:
> > On Wed, 2026-03-11 at 22:39 -0700, Eric Biggers wrote:
> > > IMA computes hashes using the crypto_shash or crypto_ahash API. The
> > > latter is used only when ima.ahash_minsize is set on the command line,
> > > and its purpose is ostensibly to make the hash computation faster.
> > >
> > > However, going off the CPU to a crypto engine and back again is actually
> > > quite slow, especially compared with the acceleration that is built into
> > > modern CPUs and the kernel now enables by default for most algorithms.
> > > Typical performance results for SHA-256 on a modern platform can be
> > > found at https://lore.kernel.org/linux-crypto/20250615184638.GA1480@sol/
> > >
> > > Partly for this reason, several other kernel subsystems have already
> > > dropped support for the crypto_ahash API.
> >
> > The performance benefit was the ability of reading and filling a buffer from
> > disk, which was slow, while the other buffer was sent to the crypto engine.
>
> On normal filesystems, sequential reads from a file already kick off
> async readahead. So the hashing and disk reads can already happen
> concurrently anyway.
>
> - Eric
I think this is fine. It was developed to be used on OMAP processors a
long time ago.
It can go away..
Ack
^ permalink raw reply
* [zohar-integrity:next-integrity.ima-sigv3-support-1 13/15] security/integrity/evm/evm_main.c:267:22: error: too many arguments to function 'integrity_digsig_verify'
From: kernel test robot @ 2026-03-17 12:02 UTC (permalink / raw)
To: Mimi Zohar; +Cc: oe-kbuild-all, linux-integrity
tree: https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git next-integrity.ima-sigv3-support-1
head: 9037cd4a36eb9554fb5968a4c1a990d44843190b
commit: d45011bbc88d112e7eea4dbb9a1b3b0081d0b30a [13/15] ima: Define asymmetric_verify_v3() to verify IMA sigv3 signatures
config: i386-randconfig-006-20260317 (https://download.01.org/0day-ci/archive/20260317/202603171952.z3Qgv7vC-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260317/202603171952.z3Qgv7vC-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603171952.z3Qgv7vC-lkp@intel.com/
All errors (new ones prefixed by >>):
security/integrity/evm/evm_main.c: In function 'evm_verify_hmac':
>> security/integrity/evm/evm_main.c:267:22: error: too many arguments to function 'integrity_digsig_verify'
267 | rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
| ^~~~~~~~~~~~~~~~~~~~~~~
In file included from security/integrity/evm/evm.h:18,
from security/integrity/evm/evm_main.c:28:
security/integrity/evm/../integrity.h:143:19: note: declared here
143 | static inline int integrity_digsig_verify(const unsigned int id,
| ^~~~~~~~~~~~~~~~~~~~~~~
vim +/integrity_digsig_verify +267 security/integrity/evm/evm_main.c
cd708c938f055c Mimi Zohar 2023-12-18 172
66dbc325afcef9 Mimi Zohar 2011-03-15 173 /*
66dbc325afcef9 Mimi Zohar 2011-03-15 174 * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
66dbc325afcef9 Mimi Zohar 2011-03-15 175 *
66dbc325afcef9 Mimi Zohar 2011-03-15 176 * Compute the HMAC on the dentry's protected set of extended attributes
7102ebcd65c1cd Mimi Zohar 2011-05-12 177 * and compare it against the stored security.evm xattr.
7102ebcd65c1cd Mimi Zohar 2011-05-12 178 *
7102ebcd65c1cd Mimi Zohar 2011-05-12 179 * For performance:
ceb5faef848b2f Tanya Agarwal 2025-01-24 180 * - use the previously retrieved xattr value and length to calculate the
66dbc325afcef9 Mimi Zohar 2011-03-15 181 * HMAC.)
7102ebcd65c1cd Mimi Zohar 2011-05-12 182 * - cache the verification result in the iint, when available.
66dbc325afcef9 Mimi Zohar 2011-03-15 183 *
66dbc325afcef9 Mimi Zohar 2011-03-15 184 * Returns integrity status
66dbc325afcef9 Mimi Zohar 2011-03-15 185 */
66dbc325afcef9 Mimi Zohar 2011-03-15 186 static enum integrity_status evm_verify_hmac(struct dentry *dentry,
66dbc325afcef9 Mimi Zohar 2011-03-15 187 const char *xattr_name,
66dbc325afcef9 Mimi Zohar 2011-03-15 188 char *xattr_value,
75a323e604fc77 Roberto Sassu 2024-02-15 189 size_t xattr_value_len)
66dbc325afcef9 Mimi Zohar 2011-03-15 190 {
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 191 struct evm_ima_xattr_data *xattr_data = NULL;
5feeb61183dde9 Matthew Garrett 2018-06-08 192 struct signature_v2_hdr *hdr;
566be59ab86c0e Mimi Zohar 2011-08-22 193 enum integrity_status evm_status = INTEGRITY_PASS;
5feeb61183dde9 Matthew Garrett 2018-06-08 194 struct evm_digest digest;
75a323e604fc77 Roberto Sassu 2024-02-15 195 struct inode *inode = d_backing_inode(dentry);
75a323e604fc77 Roberto Sassu 2024-02-15 196 struct evm_iint_cache *iint = evm_iint_inode(inode);
cdef685be5b4ae Roberto Sassu 2021-05-14 197 int rc, xattr_len, evm_immutable = 0;
66dbc325afcef9 Mimi Zohar 2011-03-15 198
50b977481fce90 Matthew Garrett 2017-11-07 199 if (iint && (iint->evm_status == INTEGRITY_PASS ||
50b977481fce90 Matthew Garrett 2017-11-07 200 iint->evm_status == INTEGRITY_PASS_IMMUTABLE))
24e0198efe0df5 Dmitry Kasatkin 2011-05-06 201 return iint->evm_status;
66dbc325afcef9 Mimi Zohar 2011-03-15 202
47add87ad18147 Stefan Berger 2024-02-23 203 /*
47add87ad18147 Stefan Berger 2024-02-23 204 * On unsupported filesystems without EVM_INIT_X509 enabled, skip
47add87ad18147 Stefan Berger 2024-02-23 205 * signature verification.
47add87ad18147 Stefan Berger 2024-02-23 206 */
5e2e4d0ea5c2c8 Stefan Berger 2024-02-23 207 if (!(evm_initialized & EVM_INIT_X509) &&
5e2e4d0ea5c2c8 Stefan Berger 2024-02-23 208 is_unsupported_hmac_fs(dentry))
cd708c938f055c Mimi Zohar 2023-12-18 209 return INTEGRITY_UNKNOWN;
cd708c938f055c Mimi Zohar 2023-12-18 210
6d38ca01c0c2d6 Dmitry Kasatkin 2011-05-06 211 /* if status is not PASS, try to check again - against -ENOMEM */
6d38ca01c0c2d6 Dmitry Kasatkin 2011-05-06 212
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 213 /* first need to know the sig type */
4609e1f18e19c3 Christian Brauner 2023-01-13 214 rc = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, XATTR_NAME_EVM,
c7c7a1a18af4c3 Tycho Andersen 2021-01-21 215 (char **)&xattr_data, 0, GFP_NOFS);
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 216 if (rc <= 0) {
1f1009791b2e81 Dmitry Kasatkin 2014-08-15 217 evm_status = INTEGRITY_FAIL;
1f1009791b2e81 Dmitry Kasatkin 2014-08-15 218 if (rc == -ENODATA) {
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 219 rc = evm_find_protected_xattrs(dentry);
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 220 if (rc > 0)
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 221 evm_status = INTEGRITY_NOLABEL;
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 222 else if (rc == 0)
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 223 evm_status = INTEGRITY_NOXATTRS; /* new file */
1f1009791b2e81 Dmitry Kasatkin 2014-08-15 224 } else if (rc == -EOPNOTSUPP) {
1f1009791b2e81 Dmitry Kasatkin 2014-08-15 225 evm_status = INTEGRITY_UNKNOWN;
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 226 }
566be59ab86c0e Mimi Zohar 2011-08-22 227 goto out;
566be59ab86c0e Mimi Zohar 2011-08-22 228 }
66dbc325afcef9 Mimi Zohar 2011-03-15 229
b1aaab22e263d0 Dmitry Kasatkin 2013-10-10 230 xattr_len = rc;
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 231
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 232 /* check value type */
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 233 switch (xattr_data->type) {
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 234 case EVM_XATTR_HMAC:
650b29dbdf2caf Thiago Jung Bauermann 2019-06-11 235 if (xattr_len != sizeof(struct evm_xattr)) {
b4bfec7f4a8642 Seth Forshee 2016-08-01 236 evm_status = INTEGRITY_FAIL;
b4bfec7f4a8642 Seth Forshee 2016-08-01 237 goto out;
b4bfec7f4a8642 Seth Forshee 2016-08-01 238 }
5feeb61183dde9 Matthew Garrett 2018-06-08 239
5feeb61183dde9 Matthew Garrett 2018-06-08 240 digest.hdr.algo = HASH_ALGO_SHA1;
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 241 rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
a652aa59068bd7 Stefan Berger 2024-02-23 242 xattr_value_len, &digest, iint);
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 243 if (rc)
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 244 break;
650b29dbdf2caf Thiago Jung Bauermann 2019-06-11 245 rc = crypto_memneq(xattr_data->data, digest.digest,
5feeb61183dde9 Matthew Garrett 2018-06-08 246 SHA1_DIGEST_SIZE);
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 247 if (rc)
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 248 rc = -EINVAL;
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 249 break;
50b977481fce90 Matthew Garrett 2017-11-07 250 case EVM_XATTR_PORTABLE_DIGSIG:
cdef685be5b4ae Roberto Sassu 2021-05-14 251 evm_immutable = 1;
cdef685be5b4ae Roberto Sassu 2021-05-14 252 fallthrough;
cdef685be5b4ae Roberto Sassu 2021-05-14 253 case EVM_IMA_XATTR_DIGSIG:
455b6c9112eff8 Roberto Sassu 2020-09-04 254 /* accept xattr with non-empty signature field */
455b6c9112eff8 Roberto Sassu 2020-09-04 255 if (xattr_len <= sizeof(struct signature_v2_hdr)) {
455b6c9112eff8 Roberto Sassu 2020-09-04 256 evm_status = INTEGRITY_FAIL;
455b6c9112eff8 Roberto Sassu 2020-09-04 257 goto out;
455b6c9112eff8 Roberto Sassu 2020-09-04 258 }
455b6c9112eff8 Roberto Sassu 2020-09-04 259
5feeb61183dde9 Matthew Garrett 2018-06-08 260 hdr = (struct signature_v2_hdr *)xattr_data;
5feeb61183dde9 Matthew Garrett 2018-06-08 261 digest.hdr.algo = hdr->hash_algo;
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 262 rc = evm_calc_hash(dentry, xattr_name, xattr_value,
a652aa59068bd7 Stefan Berger 2024-02-23 263 xattr_value_len, xattr_data->type, &digest,
a652aa59068bd7 Stefan Berger 2024-02-23 264 iint);
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 265 if (rc)
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 266 break;
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 @267 rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
b1aaab22e263d0 Dmitry Kasatkin 2013-10-10 268 (const char *)xattr_data, xattr_len,
d45011bbc88d11 Mimi Zohar 2026-03-10 269 digest.digest, digest.hdr.length,
d45011bbc88d11 Mimi Zohar 2026-03-10 270 digest.hdr.algo);
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 271 if (!rc) {
50b977481fce90 Matthew Garrett 2017-11-07 272 if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG) {
50b977481fce90 Matthew Garrett 2017-11-07 273 if (iint)
50b977481fce90 Matthew Garrett 2017-11-07 274 iint->flags |= EVM_IMMUTABLE_DIGSIG;
50b977481fce90 Matthew Garrett 2017-11-07 275 evm_status = INTEGRITY_PASS_IMMUTABLE;
70946c4ac2a9e0 Sascha Hauer 2018-03-01 276 } else if (!IS_RDONLY(inode) &&
70946c4ac2a9e0 Sascha Hauer 2018-03-01 277 !(inode->i_sb->s_readonly_remount) &&
47add87ad18147 Stefan Berger 2024-02-23 278 !IS_IMMUTABLE(inode) &&
5e2e4d0ea5c2c8 Stefan Berger 2024-02-23 279 !is_unsupported_hmac_fs(dentry)) {
c2baec7ffaf6a2 Dmitry Kasatkin 2014-10-01 280 evm_update_evmxattr(dentry, xattr_name,
c2baec7ffaf6a2 Dmitry Kasatkin 2014-10-01 281 xattr_value,
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 282 xattr_value_len);
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 283 }
50b977481fce90 Matthew Garrett 2017-11-07 284 }
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 285 break;
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 286 default:
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 287 rc = -EINVAL;
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 288 break;
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 289 }
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 290
cdef685be5b4ae Roberto Sassu 2021-05-14 291 if (rc) {
cdef685be5b4ae Roberto Sassu 2021-05-14 292 if (rc == -ENODATA)
cdef685be5b4ae Roberto Sassu 2021-05-14 293 evm_status = INTEGRITY_NOXATTRS;
cdef685be5b4ae Roberto Sassu 2021-05-14 294 else if (evm_immutable)
cdef685be5b4ae Roberto Sassu 2021-05-14 295 evm_status = INTEGRITY_FAIL_IMMUTABLE;
cdef685be5b4ae Roberto Sassu 2021-05-14 296 else
cdef685be5b4ae Roberto Sassu 2021-05-14 297 evm_status = INTEGRITY_FAIL;
cdef685be5b4ae Roberto Sassu 2021-05-14 298 }
87ac3d002d567f Mimi Zohar 2021-05-13 299 pr_debug("digest: (%d) [%*phN]\n", digest.hdr.length, digest.hdr.length,
87ac3d002d567f Mimi Zohar 2021-05-13 300 digest.digest);
7102ebcd65c1cd Mimi Zohar 2011-05-12 301 out:
7102ebcd65c1cd Mimi Zohar 2011-05-12 302 if (iint)
7102ebcd65c1cd Mimi Zohar 2011-05-12 303 iint->evm_status = evm_status;
15647eb3985ef3 Dmitry Kasatkin 2011-09-01 304 kfree(xattr_data);
7102ebcd65c1cd Mimi Zohar 2011-05-12 305 return evm_status;
66dbc325afcef9 Mimi Zohar 2011-03-15 306 }
66dbc325afcef9 Mimi Zohar 2011-03-15 307
:::::: The code at line 267 was first introduced by commit
:::::: 15647eb3985ef30dfd657038924dc85c03026733 evm: digital signature verification support
:::::: TO: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
:::::: CC: Dmitry Kasatkin <dmitry.kasatkin@intel.com>
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* [zohar-integrity:next-integrity.ima-sigv3-support-1 13/15] security/integrity/evm/evm_main.c:270:6: error: too many arguments to function call, expected 5, have 6
From: kernel test robot @ 2026-03-17 9:16 UTC (permalink / raw)
To: Mimi Zohar; +Cc: llvm, oe-kbuild-all, linux-integrity
tree: https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git next-integrity.ima-sigv3-support-1
head: 9037cd4a36eb9554fb5968a4c1a990d44843190b
commit: d45011bbc88d112e7eea4dbb9a1b3b0081d0b30a [13/15] ima: Define asymmetric_verify_v3() to verify IMA sigv3 signatures
config: i386-buildonly-randconfig-005-20260317 (https://download.01.org/0day-ci/archive/20260317/202603171719.U8qaT87C-lkp@intel.com/config)
compiler: clang version 20.1.8 (https://github.com/llvm/llvm-project 87f0227cb60147a26a1eeb4fb06e3b505e9c7261)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260317/202603171719.U8qaT87C-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202603171719.U8qaT87C-lkp@intel.com/
All errors (new ones prefixed by >>):
>> security/integrity/evm/evm_main.c:270:6: error: too many arguments to function call, expected 5, have 6
267 | rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
| ~~~~~~~~~~~~~~~~~~~~~~~
268 | (const char *)xattr_data, xattr_len,
269 | digest.digest, digest.hdr.length,
270 | digest.hdr.algo);
| ^~~~~~~~~~~~~~~
security/integrity/evm/../integrity.h:143:19: note: 'integrity_digsig_verify' declared here
143 | static inline int integrity_digsig_verify(const unsigned int id,
| ^ ~~~~~~~~~~~~~~~~~~~~~~
144 | const char *sig, int siglen,
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
145 | const char *digest, int digestlen)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
vim +270 security/integrity/evm/evm_main.c
172
173 /*
174 * evm_verify_hmac - calculate and compare the HMAC with the EVM xattr
175 *
176 * Compute the HMAC on the dentry's protected set of extended attributes
177 * and compare it against the stored security.evm xattr.
178 *
179 * For performance:
180 * - use the previously retrieved xattr value and length to calculate the
181 * HMAC.)
182 * - cache the verification result in the iint, when available.
183 *
184 * Returns integrity status
185 */
186 static enum integrity_status evm_verify_hmac(struct dentry *dentry,
187 const char *xattr_name,
188 char *xattr_value,
189 size_t xattr_value_len)
190 {
191 struct evm_ima_xattr_data *xattr_data = NULL;
192 struct signature_v2_hdr *hdr;
193 enum integrity_status evm_status = INTEGRITY_PASS;
194 struct evm_digest digest;
195 struct inode *inode = d_backing_inode(dentry);
196 struct evm_iint_cache *iint = evm_iint_inode(inode);
197 int rc, xattr_len, evm_immutable = 0;
198
199 if (iint && (iint->evm_status == INTEGRITY_PASS ||
200 iint->evm_status == INTEGRITY_PASS_IMMUTABLE))
201 return iint->evm_status;
202
203 /*
204 * On unsupported filesystems without EVM_INIT_X509 enabled, skip
205 * signature verification.
206 */
207 if (!(evm_initialized & EVM_INIT_X509) &&
208 is_unsupported_hmac_fs(dentry))
209 return INTEGRITY_UNKNOWN;
210
211 /* if status is not PASS, try to check again - against -ENOMEM */
212
213 /* first need to know the sig type */
214 rc = vfs_getxattr_alloc(&nop_mnt_idmap, dentry, XATTR_NAME_EVM,
215 (char **)&xattr_data, 0, GFP_NOFS);
216 if (rc <= 0) {
217 evm_status = INTEGRITY_FAIL;
218 if (rc == -ENODATA) {
219 rc = evm_find_protected_xattrs(dentry);
220 if (rc > 0)
221 evm_status = INTEGRITY_NOLABEL;
222 else if (rc == 0)
223 evm_status = INTEGRITY_NOXATTRS; /* new file */
224 } else if (rc == -EOPNOTSUPP) {
225 evm_status = INTEGRITY_UNKNOWN;
226 }
227 goto out;
228 }
229
230 xattr_len = rc;
231
232 /* check value type */
233 switch (xattr_data->type) {
234 case EVM_XATTR_HMAC:
235 if (xattr_len != sizeof(struct evm_xattr)) {
236 evm_status = INTEGRITY_FAIL;
237 goto out;
238 }
239
240 digest.hdr.algo = HASH_ALGO_SHA1;
241 rc = evm_calc_hmac(dentry, xattr_name, xattr_value,
242 xattr_value_len, &digest, iint);
243 if (rc)
244 break;
245 rc = crypto_memneq(xattr_data->data, digest.digest,
246 SHA1_DIGEST_SIZE);
247 if (rc)
248 rc = -EINVAL;
249 break;
250 case EVM_XATTR_PORTABLE_DIGSIG:
251 evm_immutable = 1;
252 fallthrough;
253 case EVM_IMA_XATTR_DIGSIG:
254 /* accept xattr with non-empty signature field */
255 if (xattr_len <= sizeof(struct signature_v2_hdr)) {
256 evm_status = INTEGRITY_FAIL;
257 goto out;
258 }
259
260 hdr = (struct signature_v2_hdr *)xattr_data;
261 digest.hdr.algo = hdr->hash_algo;
262 rc = evm_calc_hash(dentry, xattr_name, xattr_value,
263 xattr_value_len, xattr_data->type, &digest,
264 iint);
265 if (rc)
266 break;
267 rc = integrity_digsig_verify(INTEGRITY_KEYRING_EVM,
268 (const char *)xattr_data, xattr_len,
269 digest.digest, digest.hdr.length,
> 270 digest.hdr.algo);
271 if (!rc) {
272 if (xattr_data->type == EVM_XATTR_PORTABLE_DIGSIG) {
273 if (iint)
274 iint->flags |= EVM_IMMUTABLE_DIGSIG;
275 evm_status = INTEGRITY_PASS_IMMUTABLE;
276 } else if (!IS_RDONLY(inode) &&
277 !(inode->i_sb->s_readonly_remount) &&
278 !IS_IMMUTABLE(inode) &&
279 !is_unsupported_hmac_fs(dentry)) {
280 evm_update_evmxattr(dentry, xattr_name,
281 xattr_value,
282 xattr_value_len);
283 }
284 }
285 break;
286 default:
287 rc = -EINVAL;
288 break;
289 }
290
291 if (rc) {
292 if (rc == -ENODATA)
293 evm_status = INTEGRITY_NOXATTRS;
294 else if (evm_immutable)
295 evm_status = INTEGRITY_FAIL_IMMUTABLE;
296 else
297 evm_status = INTEGRITY_FAIL;
298 }
299 pr_debug("digest: (%d) [%*phN]\n", digest.hdr.length, digest.hdr.length,
300 digest.digest);
301 out:
302 if (iint)
303 iint->evm_status = evm_status;
304 kfree(xattr_data);
305 return evm_status;
306 }
307
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH v2 1/2] keys/trusted_keys: clean up debug message logging in the tpm backend
From: Srish Srinivasan @ 2026-03-17 3:14 UTC (permalink / raw)
To: Nayna Jain, linux-integrity, keyrings, Jarkko Sakkinen
Cc: James.Bottomley, jarkko, zohar, stefanb, linux-kernel,
linux-security-module
In-Reply-To: <7f8b8478-5cd8-4d97-bfd0-341fd5cf10f9@linux.ibm.com>
On 3/10/26 4:15 AM, Nayna Jain wrote:
>
> On 2/20/26 1:34 PM, Srish Srinivasan wrote:
>> The TPM trusted-keys backend uses a local TPM_DEBUG guard and pr_info()
>> for logging debug information.
>>
>> Replace pr_info() with pr_debug(), and use KERN_DEBUG for
>> print_hex_dump().
>> Remove TPM_DEBUG.
>>
>> No functional change intended.
> There is functional change here. This change allows secret and nonce
> in the function dump_sess() to be logged to kernel logs when dynamic
> debug is enabled. Previously, it was possible only in the debug builds
> and not the production builds at runtime. With this change, it is
> always there in production build. This can result in possible attack.
Hi Jarkko,
Could you please let us know your thoughts on this one?
And Nayna,
thanks for bringing this up.
thanks,
Srish.
>
> Instead of doing this change, I think add a comment to prevent this
> sort of change in the future.
>
> Thanks & Regards,
>
> - Nayna
>
>>
>> Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
>> Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
>> ---
>> security/keys/trusted-keys/trusted_tpm1.c | 40 +++++++----------------
>> 1 file changed, 12 insertions(+), 28 deletions(-)
>>
>> diff --git a/security/keys/trusted-keys/trusted_tpm1.c
>> b/security/keys/trusted-keys/trusted_tpm1.c
>> index c865c97aa1b4..216caef97ffc 100644
>> --- a/security/keys/trusted-keys/trusted_tpm1.c
>> +++ b/security/keys/trusted-keys/trusted_tpm1.c
>> @@ -46,28 +46,25 @@ enum {
>> SRK_keytype = 4
>> };
>> -#define TPM_DEBUG 0
>> -
>> -#if TPM_DEBUG
>> static inline void dump_options(struct trusted_key_options *o)
>> {
>> - pr_info("sealing key type %d\n", o->keytype);
>> - pr_info("sealing key handle %0X\n", o->keyhandle);
>> - pr_info("pcrlock %d\n", o->pcrlock);
>> - pr_info("pcrinfo %d\n", o->pcrinfo_len);
>> - print_hex_dump(KERN_INFO, "pcrinfo ", DUMP_PREFIX_NONE,
>> + pr_debug("sealing key type %d\n", o->keytype);
>> + pr_debug("sealing key handle %0X\n", o->keyhandle);
>> + pr_debug("pcrlock %d\n", o->pcrlock);
>> + pr_debug("pcrinfo %d\n", o->pcrinfo_len);
>> + print_hex_dump(KERN_DEBUG, "pcrinfo ", DUMP_PREFIX_NONE,
>> 16, 1, o->pcrinfo, o->pcrinfo_len, 0);
>> }
>> static inline void dump_sess(struct osapsess *s)
>> {
>> - print_hex_dump(KERN_INFO, "trusted-key: handle ", DUMP_PREFIX_NONE,
>> + print_hex_dump(KERN_DEBUG, "trusted-key: handle ",
>> DUMP_PREFIX_NONE,
>> 16, 1, &s->handle, 4, 0);
>> - pr_info("secret:\n");
>> - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
>> + pr_debug("secret:\n");
>> + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE,
>> 16, 1, &s->secret, SHA1_DIGEST_SIZE, 0);
>> - pr_info("trusted-key: enonce:\n");
>> - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE,
>> + pr_debug("trusted-key: enonce:\n");
>> + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE,
>> 16, 1, &s->enonce, SHA1_DIGEST_SIZE, 0);
>> }
>> @@ -75,23 +72,10 @@ static inline void dump_tpm_buf(unsigned char
>> *buf)
>> {
>> int len;
>> - pr_info("\ntpm buffer\n");
>> + pr_debug("\ntpm buffer\n");
>> len = LOAD32(buf, TPM_SIZE_OFFSET);
>> - print_hex_dump(KERN_INFO, "", DUMP_PREFIX_NONE, 16, 1, buf, len,
>> 0);
>> -}
>> -#else
>> -static inline void dump_options(struct trusted_key_options *o)
>> -{
>> -}
>> -
>> -static inline void dump_sess(struct osapsess *s)
>> -{
>> -}
>> -
>> -static inline void dump_tpm_buf(unsigned char *buf)
>> -{
>> + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_NONE, 16, 1, buf,
>> len, 0);
>> }
>> -#endif
>> static int TSS_rawhmac(unsigned char *digest, const unsigned char
>> *key,
>> unsigned int keylen, ...)
^ permalink raw reply
* [PATCH v3 2/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: Jeff Layton @ 2026-03-16 19:02 UTC (permalink / raw)
To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn
Cc: David Laight, linux-nilfs, linux-kernel, linux-integrity,
linux-security-module, linux-fsdevel, Jeff Layton,
kernel test robot
In-Reply-To: <20260316-iino-u64-v3-0-d1076b8f7a20@kernel.org>
With the change to make inode->i_ino a u64, the build started failing on
32-bit ARM with:
ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!
Fix this by using udiv_u64() for the division.
For finding the index into the group, switch to using a bitwise &
operation since that's more efficient. With this change however,
NILFS_BMAP_GROUP_DIV must be a power of two, so add a compile-time
assertion for that.
Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
fs/nilfs2/bmap.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..5f0f1f283af0208e1879e2e84b0b5b9629fd6b8a 100644
--- a/fs/nilfs2/bmap.c
+++ b/fs/nilfs2/bmap.c
@@ -450,18 +450,25 @@ __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *bmap, __u64 key)
return NILFS_BMAP_INVALID_PTR;
}
-#define NILFS_BMAP_GROUP_DIV 8
+#define NILFS_BMAP_GROUP_DIV 8 /* must be power of 2 */
+
__u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
{
struct inode *dat = nilfs_bmap_get_dat(bmap);
unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
- unsigned long group = bmap->b_inode->i_ino / entries_per_group;
+ unsigned long group;
+ u32 index;
+
+ BUILD_BUG_ON_NOT_POWER_OF_2(NILFS_BMAP_GROUP_DIV);
+
+ group = div_u64(bmap->b_inode->i_ino, entries_per_group);
+ index = bmap->b_inode->i_ino & (NILFS_BMAP_GROUP_DIV - 1);
return group * entries_per_group +
- (bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
- (entries_per_group / NILFS_BMAP_GROUP_DIV);
+ index * (entries_per_group / NILFS_BMAP_GROUP_DIV);
}
+
static struct lock_class_key nilfs_bmap_dat_lock_key;
static struct lock_class_key nilfs_bmap_mdt_lock_key;
--
2.53.0
^ permalink raw reply related
* [PATCH v3 1/2] EVM: add comment describing why ino field is still unsigned long
From: Jeff Layton @ 2026-03-16 19:02 UTC (permalink / raw)
To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn
Cc: David Laight, linux-nilfs, linux-kernel, linux-integrity,
linux-security-module, linux-fsdevel, Jeff Layton
In-Reply-To: <20260316-iino-u64-v3-0-d1076b8f7a20@kernel.org>
Mimi pointed out that we didn't widen the inode number field in struct
h_misc alongside the inode->i_ino widening. While we could make an
equivalent change there, that would require EVM resigning on all 32-bit
hosts.
Instead, leave the field as an unsigned long. This should have no effect
on 64-bit hosts, and allow things to continue working on 32-bit hosts in
the cases where the i_ino fits in 32-bits.
Add a comment explaining why it's being left as unsigned long.
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
security/integrity/evm/evm_crypto.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index c0ca4eedb0fe5d5c30f45f515a4bc90248ec64ea..1c41af2f91a60a714878ff93b554c90e45546503 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -144,6 +144,12 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
char type, char *digest)
{
struct h_misc {
+ /*
+ * Although inode->i_ino is now u64, this field remains
+ * unsigned long to allow existing HMAC and signatures from
+ * 32-bit hosts to continue working when i_ino hasn't changed
+ * and fits in a u32.
+ */
unsigned long ino;
__u32 generation;
uid_t uid;
--
2.53.0
^ permalink raw reply related
* [PATCH v3 0/2] vfs: follow-on fixes for i_ino widening
From: Jeff Layton @ 2026-03-16 19:02 UTC (permalink / raw)
To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn
Cc: David Laight, linux-nilfs, linux-kernel, linux-integrity,
linux-security-module, linux-fsdevel, Jeff Layton,
kernel test robot
Just some patches to fix follow-on issues reported after the
inode->i_ino widening series. Christian, could you toss these
onto the vfs-7.1.kino branch?
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
Changes in v3:
- nilfs2: find index with bitwise & operation instead of div_u64_rem()
- add compile-time assertion that NILFS_BMAP_GROUP_DIV is power of two
- Link to v2: https://lore.kernel.org/r/20260313-iino-u64-v2-0-f9abda2464d5@kernel.org
Changes in v2:
- rename variable in nilfs2 patch from "rem" to "index"
- reword comment and commit log for better accuracy in EVM patch
---
Jeff Layton (2):
EVM: add comment describing why ino field is still unsigned long
nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
fs/nilfs2/bmap.c | 15 +++++++++++----
security/integrity/evm/evm_crypto.c | 6 ++++++
2 files changed, 17 insertions(+), 4 deletions(-)
---
base-commit: 9840bb66e7e5dffd72b03201318f154a10b06b4a
change-id: 20260310-iino-u64-424fa570d850
Best regards,
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* Re: [PATCH v2 1/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: Jeff Layton @ 2026-03-16 18:50 UTC (permalink / raw)
To: Ryusuke Konishi, David Laight
Cc: Viacheslav Dubeyko, Christian Brauner, Mimi Zohar, Roberto Sassu,
Dmitry Kasatkin, Eric Snowberg, Paul Moore, James Morris,
Serge E. Hallyn, linux-nilfs, linux-kernel, linux-integrity,
linux-security-module, linux-fsdevel, kernel test robot
In-Reply-To: <CAKFNMomRoq+rxF2HzzTpWhju+GCm3p3fjhm7e9mmvZKdsJHwZA@mail.gmail.com>
On Tue, 2026-03-17 at 03:06 +0900, Ryusuke Konishi wrote:
> On Sat, Mar 14, 2026 at 9:59 PM Jeff Layton wrote:
> >
> > On Sat, 2026-03-14 at 12:47 +0000, David Laight wrote:
> > > On Fri, 13 Mar 2026 14:45:20 -0400
> > > Jeff Layton <jlayton@kernel.org> wrote:
> > >
> > > > With the change to make inode->i_ino a u64, the build started failing on
> > > > 32-bit ARM with:
> > > >
> > > > ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!
> > > >
> > > > Fix this by using the 64-bit division interfaces in
> > > > nilfs_bmap_find_target_in_group().
> > > >
> > > > Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
> > > > Reported-by: kernel test robot <lkp@intel.com>
> > > > Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
> > > > Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
> > > > Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
> > > > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > > > ---
> > > > fs/nilfs2/bmap.c | 9 ++++++---
> > > > 1 file changed, 6 insertions(+), 3 deletions(-)
> > > >
> > > > diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
> > > > index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..abcf5252578ad24f694bfccf525893674bfcb4bc 100644
> > > > --- a/fs/nilfs2/bmap.c
> > > > +++ b/fs/nilfs2/bmap.c
> > > > @@ -455,11 +455,14 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
> > > > {
> > > > struct inode *dat = nilfs_bmap_get_dat(bmap);
> > > > unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
> > > > - unsigned long group = bmap->b_inode->i_ino / entries_per_group;
> > >
> > > Are you sure entries_per_group can be more than 32 bits?
> > > It looks like something that will be the same size on 32 and 64bit.
> > >
> >
> > I'm not sure of anything here. I'm just want to get this to compile on
> > all arches. FWIW, I'm not looking to optimize anything in this patch.
> >
> > > > + unsigned long group;
> > > > + u32 index;
> > > > +
> > > > + group = div_u64(bmap->b_inode->i_ino, entries_per_group);
> > >
> > > You don't need the full 64 by 64 divide.
> > > IIRC there are both div_u64_u32() and div_u64_ulong().
>
> Isn't the type of divisor in div_u64() u32?
> Since entries_per_group cannot exceed 32 bits according to the current
> specification, I think using div_u64() is fine.
>
Yep, it is:
static inline u64 div_u64(u64 dividend, u32 divisor)
> > >
> > > > + div_u64_rem(bmap->b_inode->i_ino, NILFS_BMAP_GROUP_DIV, &index);
> > >
> > > NILFD_BMAP_GROUP_DIV is 8 (and probably has to be a power of 2).
> > > So:
> > > index = bmap->b_inode->i_ino & (NILFS_BMAP_GROUP_DIV - 1);
> > > is the same and likely much faster to calculate.
> > > (The compiler will have done that optimisation before.)
> > >
> > >
> >
> > That all sounds reasonable to me. At this point though, it would be
> > better if the NILFS2 folks stepped in with how they'd prefer this be
> > done.
>
> Yes, indeed. It seems that the application of optimizations will
> change, so this proposed correction is better.
>
> Since NILFS_BMAP_GROUP_DIV is a fixed constant and cannot be anything
> other than a power of 2, could you please adopt this proposed
> correction with the following comment?
>
> #define NILFS_BMAP_GROUP_DIV 8 /* must be a power of 2 */
>
Even better, lets use a compile-time assertion:
BUILD_BUG_ON_NOT_POWER_OF_TWO(NILFS_BMAP_GROUP_DIV);
I'll send a respin.
Thanks!
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* Re: [PATCH v2 1/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: Ryusuke Konishi @ 2026-03-16 18:06 UTC (permalink / raw)
To: David Laight, Jeff Layton
Cc: Viacheslav Dubeyko, Christian Brauner, Mimi Zohar, Roberto Sassu,
Dmitry Kasatkin, Eric Snowberg, Paul Moore, James Morris,
Serge E. Hallyn, linux-nilfs, linux-kernel, linux-integrity,
linux-security-module, linux-fsdevel, kernel test robot
In-Reply-To: <361258925536e2280ce62c5e49531af5c42aa491.camel@kernel.org>
On Sat, Mar 14, 2026 at 9:59 PM Jeff Layton wrote:
>
> On Sat, 2026-03-14 at 12:47 +0000, David Laight wrote:
> > On Fri, 13 Mar 2026 14:45:20 -0400
> > Jeff Layton <jlayton@kernel.org> wrote:
> >
> > > With the change to make inode->i_ino a u64, the build started failing on
> > > 32-bit ARM with:
> > >
> > > ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!
> > >
> > > Fix this by using the 64-bit division interfaces in
> > > nilfs_bmap_find_target_in_group().
> > >
> > > Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
> > > Reported-by: kernel test robot <lkp@intel.com>
> > > Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
> > > Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
> > > Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
> > > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > > ---
> > > fs/nilfs2/bmap.c | 9 ++++++---
> > > 1 file changed, 6 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
> > > index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..abcf5252578ad24f694bfccf525893674bfcb4bc 100644
> > > --- a/fs/nilfs2/bmap.c
> > > +++ b/fs/nilfs2/bmap.c
> > > @@ -455,11 +455,14 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
> > > {
> > > struct inode *dat = nilfs_bmap_get_dat(bmap);
> > > unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
> > > - unsigned long group = bmap->b_inode->i_ino / entries_per_group;
> >
> > Are you sure entries_per_group can be more than 32 bits?
> > It looks like something that will be the same size on 32 and 64bit.
> >
>
> I'm not sure of anything here. I'm just want to get this to compile on
> all arches. FWIW, I'm not looking to optimize anything in this patch.
>
> > > + unsigned long group;
> > > + u32 index;
> > > +
> > > + group = div_u64(bmap->b_inode->i_ino, entries_per_group);
> >
> > You don't need the full 64 by 64 divide.
> > IIRC there are both div_u64_u32() and div_u64_ulong().
Isn't the type of divisor in div_u64() u32?
Since entries_per_group cannot exceed 32 bits according to the current
specification, I think using div_u64() is fine.
> >
> > > + div_u64_rem(bmap->b_inode->i_ino, NILFS_BMAP_GROUP_DIV, &index);
> >
> > NILFD_BMAP_GROUP_DIV is 8 (and probably has to be a power of 2).
> > So:
> > index = bmap->b_inode->i_ino & (NILFS_BMAP_GROUP_DIV - 1);
> > is the same and likely much faster to calculate.
> > (The compiler will have done that optimisation before.)
> >
> >
>
> That all sounds reasonable to me. At this point though, it would be
> better if the NILFS2 folks stepped in with how they'd prefer this be
> done.
Yes, indeed. It seems that the application of optimizations will
change, so this proposed correction is better.
Since NILFS_BMAP_GROUP_DIV is a fixed constant and cannot be anything
other than a power of 2, could you please adopt this proposed
correction with the following comment?
#define NILFS_BMAP_GROUP_DIV 8 /* must be a power of 2 */
Thanks,
Ryusuke Konishi
>
> >
> > >
> > > return group * entries_per_group +
> > > - (bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
> > > - (entries_per_group / NILFS_BMAP_GROUP_DIV);
> > > + index * (entries_per_group / NILFS_BMAP_GROUP_DIV);
> > > }
> > >
> > > static struct lock_class_key nilfs_bmap_dat_lock_key;
> > >
>
> --
> Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* Re: [PATCH] ima: remove buggy support for asynchronous hashes
From: Eric Biggers @ 2026-03-14 18:25 UTC (permalink / raw)
To: Mimi Zohar
Cc: linux-integrity, Roberto Sassu, Dmitry Kasatkin, linux-crypto,
linux-kernel
In-Reply-To: <1c5f16f0913bae48bf2f24feaaaf3525ecdf4c97.camel@linux.ibm.com>
On Thu, Mar 12, 2026 at 07:29:05PM -0400, Mimi Zohar wrote:
> On Wed, 2026-03-11 at 22:39 -0700, Eric Biggers wrote:
> > IMA computes hashes using the crypto_shash or crypto_ahash API. The
> > latter is used only when ima.ahash_minsize is set on the command line,
> > and its purpose is ostensibly to make the hash computation faster.
> >
> > However, going off the CPU to a crypto engine and back again is actually
> > quite slow, especially compared with the acceleration that is built into
> > modern CPUs and the kernel now enables by default for most algorithms.
> > Typical performance results for SHA-256 on a modern platform can be
> > found at https://lore.kernel.org/linux-crypto/20250615184638.GA1480@sol/
> >
> > Partly for this reason, several other kernel subsystems have already
> > dropped support for the crypto_ahash API.
>
> The performance benefit was the ability of reading and filling a buffer from
> disk, which was slow, while the other buffer was sent to the crypto engine.
On normal filesystems, sequential reads from a file already kick off
async readahead. So the hashing and disk reads can already happen
concurrently anyway.
- Eric
^ permalink raw reply
* Re: [PATCH v2 1/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: Jeff Layton @ 2026-03-14 12:59 UTC (permalink / raw)
To: David Laight
Cc: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn, linux-nilfs,
linux-kernel, linux-integrity, linux-security-module,
linux-fsdevel, kernel test robot
In-Reply-To: <20260314124748.1ccdf93b@pumpkin>
On Sat, 2026-03-14 at 12:47 +0000, David Laight wrote:
> On Fri, 13 Mar 2026 14:45:20 -0400
> Jeff Layton <jlayton@kernel.org> wrote:
>
> > With the change to make inode->i_ino a u64, the build started failing on
> > 32-bit ARM with:
> >
> > ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!
> >
> > Fix this by using the 64-bit division interfaces in
> > nilfs_bmap_find_target_in_group().
> >
> > Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
> > Reported-by: kernel test robot <lkp@intel.com>
> > Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
> > Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
> > Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
> > Signed-off-by: Jeff Layton <jlayton@kernel.org>
> > ---
> > fs/nilfs2/bmap.c | 9 ++++++---
> > 1 file changed, 6 insertions(+), 3 deletions(-)
> >
> > diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
> > index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..abcf5252578ad24f694bfccf525893674bfcb4bc 100644
> > --- a/fs/nilfs2/bmap.c
> > +++ b/fs/nilfs2/bmap.c
> > @@ -455,11 +455,14 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
> > {
> > struct inode *dat = nilfs_bmap_get_dat(bmap);
> > unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
> > - unsigned long group = bmap->b_inode->i_ino / entries_per_group;
>
> Are you sure entries_per_group can be more than 32 bits?
> It looks like something that will be the same size on 32 and 64bit.
>
I'm not sure of anything here. I'm just want to get this to compile on
all arches. FWIW, I'm not looking to optimize anything in this patch.
> > + unsigned long group;
> > + u32 index;
> > +
> > + group = div_u64(bmap->b_inode->i_ino, entries_per_group);
>
> You don't need the full 64 by 64 divide.
> IIRC there are both div_u64_u32() and div_u64_ulong().
>
> > + div_u64_rem(bmap->b_inode->i_ino, NILFS_BMAP_GROUP_DIV, &index);
>
> NILFD_BMAP_GROUP_DIV is 8 (and probably has to be a power of 2).
> So:
> index = bmap->b_inode->i_ino & (NILFS_BMAP_GROUP_DIV - 1);
> is the same and likely much faster to calculate.
> (The compiler will have done that optimisation before.)
>
>
That all sounds reasonable to me. At this point though, it would be
better if the NILFS2 folks stepped in with how they'd prefer this be
done.
>
> >
> > return group * entries_per_group +
> > - (bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
> > - (entries_per_group / NILFS_BMAP_GROUP_DIV);
> > + index * (entries_per_group / NILFS_BMAP_GROUP_DIV);
> > }
> >
> > static struct lock_class_key nilfs_bmap_dat_lock_key;
> >
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* Re: [PATCH v2 1/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: David Laight @ 2026-03-14 12:47 UTC (permalink / raw)
To: Jeff Layton
Cc: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn, linux-nilfs,
linux-kernel, linux-integrity, linux-security-module,
linux-fsdevel, kernel test robot
In-Reply-To: <20260313-iino-u64-v2-1-f9abda2464d5@kernel.org>
On Fri, 13 Mar 2026 14:45:20 -0400
Jeff Layton <jlayton@kernel.org> wrote:
> With the change to make inode->i_ino a u64, the build started failing on
> 32-bit ARM with:
>
> ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!
>
> Fix this by using the 64-bit division interfaces in
> nilfs_bmap_find_target_in_group().
>
> Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
> Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
> ---
> fs/nilfs2/bmap.c | 9 ++++++---
> 1 file changed, 6 insertions(+), 3 deletions(-)
>
> diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
> index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..abcf5252578ad24f694bfccf525893674bfcb4bc 100644
> --- a/fs/nilfs2/bmap.c
> +++ b/fs/nilfs2/bmap.c
> @@ -455,11 +455,14 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
> {
> struct inode *dat = nilfs_bmap_get_dat(bmap);
> unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
> - unsigned long group = bmap->b_inode->i_ino / entries_per_group;
Are you sure entries_per_group can be more than 32 bits?
It looks like something that will be the same size on 32 and 64bit.
> + unsigned long group;
> + u32 index;
> +
> + group = div_u64(bmap->b_inode->i_ino, entries_per_group);
You don't need the full 64 by 64 divide.
IIRC there are both div_u64_u32() and div_u64_ulong().
> + div_u64_rem(bmap->b_inode->i_ino, NILFS_BMAP_GROUP_DIV, &index);
NILFD_BMAP_GROUP_DIV is 8 (and probably has to be a power of 2).
So:
index = bmap->b_inode->i_ino & (NILFS_BMAP_GROUP_DIV - 1);
is the same and likely much faster to calculate.
(The compiler will have done that optimisation before.)
David
>
> return group * entries_per_group +
> - (bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
> - (entries_per_group / NILFS_BMAP_GROUP_DIV);
> + index * (entries_per_group / NILFS_BMAP_GROUP_DIV);
> }
>
> static struct lock_class_key nilfs_bmap_dat_lock_key;
>
^ permalink raw reply
* Re: [PATCH v2 2/2] EVM: add comment describing why ino field is still unsigned long
From: Mimi Zohar @ 2026-03-13 19:50 UTC (permalink / raw)
To: Jeff Layton, Ryusuke Konishi, Viacheslav Dubeyko,
Christian Brauner, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn
Cc: linux-nilfs, linux-kernel, linux-integrity, linux-security-module,
linux-fsdevel
In-Reply-To: <20260313-iino-u64-v2-2-f9abda2464d5@kernel.org>
On Fri, 2026-03-13 at 14:45 -0400, Jeff Layton wrote:
> Mimi pointed out that we didn't widen the inode number field in struct
> h_misc alongside the inode->i_ino widening. While we could make an
> equivalent change there, that would require EVM resigning on all 32-bit
> hosts.
>
> Instead, leave the field as an unsigned long. This should have no effect
> on 64-bit hosts, and allow things to continue working on 32-bit hosts in
> the cases where the i_ino fits in 32-bits.
>
> Add a comment explaining why it's being left as unsigned long.
>
> Cc: Mimi Zohar <zohar@linux.ibm.com>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
Thanks, Jeff.
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
> ---
> security/integrity/evm/evm_crypto.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
> index c0ca4eedb0fe5d5c30f45f515a4bc90248ec64ea..1c41af2f91a60a714878ff93b554c90e45546503 100644
> --- a/security/integrity/evm/evm_crypto.c
> +++ b/security/integrity/evm/evm_crypto.c
> @@ -144,6 +144,12 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
> char type, char *digest)
> {
> struct h_misc {
> + /*
> + * Although inode->i_ino is now u64, this field remains
> + * unsigned long to allow existing HMAC and signatures from
> + * 32-bit hosts to continue working when i_ino hasn't changed
> + * and fits in a u32.
> + */
> unsigned long ino;
> __u32 generation;
> uid_t uid;
^ permalink raw reply
* [PATCH v2 2/2] EVM: add comment describing why ino field is still unsigned long
From: Jeff Layton @ 2026-03-13 18:45 UTC (permalink / raw)
To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn
Cc: linux-nilfs, linux-kernel, linux-integrity, linux-security-module,
linux-fsdevel, Jeff Layton
In-Reply-To: <20260313-iino-u64-v2-0-f9abda2464d5@kernel.org>
Mimi pointed out that we didn't widen the inode number field in struct
h_misc alongside the inode->i_ino widening. While we could make an
equivalent change there, that would require EVM resigning on all 32-bit
hosts.
Instead, leave the field as an unsigned long. This should have no effect
on 64-bit hosts, and allow things to continue working on 32-bit hosts in
the cases where the i_ino fits in 32-bits.
Add a comment explaining why it's being left as unsigned long.
Cc: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
security/integrity/evm/evm_crypto.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index c0ca4eedb0fe5d5c30f45f515a4bc90248ec64ea..1c41af2f91a60a714878ff93b554c90e45546503 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -144,6 +144,12 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
char type, char *digest)
{
struct h_misc {
+ /*
+ * Although inode->i_ino is now u64, this field remains
+ * unsigned long to allow existing HMAC and signatures from
+ * 32-bit hosts to continue working when i_ino hasn't changed
+ * and fits in a u32.
+ */
unsigned long ino;
__u32 generation;
uid_t uid;
--
2.53.0
^ permalink raw reply related
* [PATCH v2 1/2] nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
From: Jeff Layton @ 2026-03-13 18:45 UTC (permalink / raw)
To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn
Cc: linux-nilfs, linux-kernel, linux-integrity, linux-security-module,
linux-fsdevel, Jeff Layton, kernel test robot
In-Reply-To: <20260313-iino-u64-v2-0-f9abda2464d5@kernel.org>
With the change to make inode->i_ino a u64, the build started failing on
32-bit ARM with:
ERROR: modpost: "__aeabi_uldivmod" [fs/nilfs2/nilfs2.ko] undefined!
Fix this by using the 64-bit division interfaces in
nilfs_bmap_find_target_in_group().
Fixes: 998a59d371c2 ("treewide: fix missed i_ino format specifier conversions")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202603100602.KPxiClIO-lkp@intel.com/
Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
Acked-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
fs/nilfs2/bmap.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c
index 824f2bd91c167965ec3a660202b6e6c5f1fe007e..abcf5252578ad24f694bfccf525893674bfcb4bc 100644
--- a/fs/nilfs2/bmap.c
+++ b/fs/nilfs2/bmap.c
@@ -455,11 +455,14 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap)
{
struct inode *dat = nilfs_bmap_get_dat(bmap);
unsigned long entries_per_group = nilfs_palloc_entries_per_group(dat);
- unsigned long group = bmap->b_inode->i_ino / entries_per_group;
+ unsigned long group;
+ u32 index;
+
+ group = div_u64(bmap->b_inode->i_ino, entries_per_group);
+ div_u64_rem(bmap->b_inode->i_ino, NILFS_BMAP_GROUP_DIV, &index);
return group * entries_per_group +
- (bmap->b_inode->i_ino % NILFS_BMAP_GROUP_DIV) *
- (entries_per_group / NILFS_BMAP_GROUP_DIV);
+ index * (entries_per_group / NILFS_BMAP_GROUP_DIV);
}
static struct lock_class_key nilfs_bmap_dat_lock_key;
--
2.53.0
^ permalink raw reply related
* [PATCH v2 0/2] vfs: follow-on fixes for i_ino widening
From: Jeff Layton @ 2026-03-13 18:45 UTC (permalink / raw)
To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn
Cc: linux-nilfs, linux-kernel, linux-integrity, linux-security-module,
linux-fsdevel, Jeff Layton, kernel test robot
Just some patches to fix follow-on issues reported after the
inode->i_ino widening series. Christian, could you toss these
onto the vfs-7.1.kino branch?
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
Changes in v2:
- rename variable in nilfs2 patch from "rem" to "index"
- reword comment and commit log for better accuracy in EVM patch
---
Jeff Layton (2):
nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
EVM: add comment describing why ino field is still unsigned long
fs/nilfs2/bmap.c | 9 ++++++---
security/integrity/evm/evm_crypto.c | 6 ++++++
2 files changed, 12 insertions(+), 3 deletions(-)
---
base-commit: 9840bb66e7e5dffd72b03201318f154a10b06b4a
change-id: 20260310-iino-u64-424fa570d850
Best regards,
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
* [PATCH v2 0/2] vfs: follow-on fixes for i_ino widening
From: Jeff Layton @ 2026-03-13 18:44 UTC (permalink / raw)
To: Ryusuke Konishi, Viacheslav Dubeyko, Christian Brauner,
Mimi Zohar, Roberto Sassu, Dmitry Kasatkin, Eric Snowberg,
Paul Moore, James Morris, Serge E. Hallyn
Cc: linux-nilfs, linux-kernel, linux-integrity, linux-security-module,
Jeff Layton, kernel test robot
Just some patches to fix follow-on issues reported after the
inode->i_ino widening series. Christian, could you toss these
onto the vfs-7.1.kino branch?
Signed-off-by: Jeff Layton <jlayton@kernel.org>
---
Changes in v2:
- rename variable in nilfs2 patch from "rem" to "index"
- reword comment and commit log for better accuracy in EVM patch
---
Jeff Layton (2):
nilfs2: fix 64-bit division operations in nilfs_bmap_find_target_in_group()
EVM: add comment describing why ino field is still unsigned long
fs/nilfs2/bmap.c | 9 ++++++---
security/integrity/evm/evm_crypto.c | 6 ++++++
2 files changed, 12 insertions(+), 3 deletions(-)
---
base-commit: 9840bb66e7e5dffd72b03201318f154a10b06b4a
change-id: 20260310-iino-u64-424fa570d850
Best regards,
--
Jeff Layton <jlayton@kernel.org>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox