Linux Integrity Measurement development
 help / color / mirror / Atom feed
* Re: [PATCH v4 1/2] ima: measure loaded policy after write on securityfs policy file
From: Mimi Zohar @ 2026-06-25 14:17 UTC (permalink / raw)
  To: Enrico Bravi, linux-integrity, dmitry.kasatkin, roberto.sassu
  Cc: eric.snowberg
In-Reply-To: <1f23b6cb35538f471dbb68534308784616130cb9.camel@linux.ibm.com>

On Wed, 2026-06-24 at 16:35 -0400, Mimi Zohar wrote:
[...]

> > diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> > index f7f940a76922..0a70d10da70a 100644
> > --- a/security/integrity/ima/ima_policy.c
> > +++ b/security/integrity/ima/ima_policy.c
> 
> > @@ -2379,3 +2378,70 @@ bool ima_appraise_signature(enum kernel_read_file_id id)
> >  	return found;
> >  }
> >  #endif /* CONFIG_IMA_APPRAISE && CONFIG_INTEGRITY_TRUSTED_KEYRING */
> > +
> > +/**
> > +* ima_measure_loaded_policy - measure the active IMA policy ruleset
> > +*
> > +* Must be called with ima_write_mutex held, as it performs two
> > +* separate RCU read passes over ima_rules and relies on the mutex
> > +* to prevent concurrent policy updates between them.
> > +*/

Hi Enrico,

I forgot to mention that the kernel-doc formatting is off.  Refer to
checkpatch.pl for the details.  Either change it to a regular comment or format
it properly.

thanks,

Mimi
> 

^ permalink raw reply

* Re: [PATCH] ima: correctly recover number of violations after kexec
From: Roberto Sassu @ 2026-06-25 13:10 UTC (permalink / raw)
  To: Enrico Bravi, linux-integrity, zohar, dmitry.kasatkin,
	roberto.sassu
  Cc: eric.snowberg
In-Reply-To: <20260619191452.7179-1-enrico.bravi@polito.it>

On Fri, 2026-06-19 at 21:14 +0200, Enrico Bravi wrote:
> When recovering the measurement list after kexec(), the number of
> violations is not recovered as well, causing a mismatch between the
> number reported by the <securityfs>/ima/violations user interface and
> the actual value. In addition, currently it is assumed that when
> recovering an entry, this is a violation if the template data hash
> read from the kexec buffer is an all-zero hash, which can actually be a
> valid hash.

This sentence is a bit convoluted. Please rework it.

> Verify that an all-zero hash corresponds to a violation and consequently
> correctly recover the number of violations.

We need to clarify that this patch only fixes false positives (a record
is declared as a violation even if it isn't, and we fix it by cross-
checking the SHA1 of the template data).

However, we are not fixing the false negatives (if the SHA1 of the
template data is zeros, we don't declare it as a violation, but it can
potentially be).

> Reported-by: Roberto Sassu <roberto.sassu@huawei.com>
> Closes: https://github.com/linux-integrity/linux/issues/13
> Signed-off-by: Enrico Bravi <enrico.bravi@polito.it>
> 
> ---
>  security/integrity/ima/ima_template.c | 28 ++++++++++++++++++++-------
>  1 file changed, 21 insertions(+), 7 deletions(-)
> 
> diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
> index 7034573fb41e..147f228ed246 100644
> --- a/security/integrity/ima/ima_template.c
> +++ b/security/integrity/ima/ima_template.c
> @@ -430,6 +430,7 @@ int ima_restore_measurement_list(loff_t size, void *buf)
>  	DECLARE_BITMAP(hdr_mask, HDR__LAST);
>  	unsigned long count = 0;
>  	int ret = 0;
> +	int i;
>  
>  	if (!buf || size < sizeof(*khdr))
>  		return 0;
> @@ -515,15 +516,28 @@ int ima_restore_measurement_list(loff_t size, void *buf)
>  		if (ret < 0)
>  			break;
>  
> -		if (memcmp(hdr[HDR_DIGEST].data, zero, sizeof(zero))) {
> -			ret = ima_calc_field_array_hash(
> -						&entry->template_data[0],
> +		ret = ima_calc_field_array_hash(&entry->template_data[0],
>  						entry);
> -			if (ret < 0) {
> -				pr_err("cannot calculate template digest\n");
> -				ret = -EINVAL;
> -				break;
> +		if (ret < 0) {
> +			pr_err("cannot calculate template digest\n");
> +			ret = -EINVAL;
> +			break;
> +		}
> +
> +		if (!memcmp(hdr[HDR_DIGEST].data, zero, sizeof(zero)) &&
> +		    memcmp(entry->digests[ima_sha1_idx].digest, zero, sizeof(zero))) {

Here it would be helpful to have a comment saying that we are reverting
the effect of ima_calc_field_array_hash(): we tried to verify if the
entry is a violation, it is, but then we have to set the template
digest back to zero after the calculation.

> +			for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++) {
> +				/* Unmapped TPM algorithms */
> +				if (!ima_algo_array[i].tfm) {
> +					memset(entry->digests[i].digest, 0,
> +					       TPM_DIGEST_SIZE);
> +					continue;
> +				}
> +
> +				memset(entry->digests[i].digest, 0,
> +				       ima_algo_array[i].digest_size);

Maybe we can just use the instruction above instead of differentiating
for unmapped algorithms? digest_size is taken from the TPM in that
case.

Thanks

Roberto

>  			}
> +			atomic_long_inc(&ima_htable.violations);
>  		}
>  
>  		entry->pcr = !ima_canonical_fmt ? *(u32 *)(hdr[HDR_PCR].data) :
> 
> base-commit: 8cd9520d35a6c38db6567e97dd93b1f11f185dc6


^ permalink raw reply

* [ANNOUNCE/CFP] Linux Plumbers 2026 Containers and Checkpoint/Restore Microconference
From: Kamalesh Babulal @ 2026-06-25  3:55 UTC (permalink / raw)
  To: cgroups, containers, bpf, linux-fsdevel, linux-api,
	linux-integrity, criu, lxc-devel, fuse-devel
  Cc: Stéphane Graber, Mike Rapoport, Christian Brauner,
	Michal Koutný, Adrian Reber, Kamalesh Babulal

Hello,

We are pleased to announce the Call for Proposals for the Containers and
Checkpoint/Restore Microconference[0] at Linux Plumbers Conference 2026,
taking place in Prague, Czechia, from October 5 to 7, 2026.

This microconference will focus on current work and open problems in
containers, checkpoint/restore, kernel interfaces, and related userspace
tooling. We hope to bring together people working on container
runtimes, CRIU, init systems, distributions, orchestration systems, and
the kernel interfaces that make these pieces work together.

Topics of interest include, but are not limited to:

  - New VFS and syscall interfaces relevant to containers, including
    work around idmapped mounts

  - Closing remaining gaps between cgroup v1 and cgroup v2, and making
    migration easier

  - The growing role of eBPF in container runtimes, observability,
    policy enforcement, and checkpoint/restore

  - Mechanisms for mediating and intercepting increasingly complex
    system calls

  - Lowering the barriers to practical use of user namespaces

  - Attestation, measurement, and other approaches to establishing
    container integrity

  - Better resource-control interfaces and limits for containerized
    workloads

  - Keeping CRIU working smoothly on modern Linux distributions

  - Checkpoint/restore support for GPUs and similar accelerators

  - Restoring FUSE daemons and related userspace services

  - Handling restartable sequences correctly during checkpoint and
    restore

  - Support for newly added kernel features and interfaces

  - Shadow stack support on x86 and arm64

  - Support for madvise(MADV_GUARD_INSTALL) and mseal()

  - pidfd-based checkpoint/restore, including process-exit information

We are also interested in additional topics that may emerge as work
evolves over the coming months. Ongoing development work, operational
experience, unresolved kernel API questions, and cross-project
coordination topics are all welcome.

We encourage you to bring open questions, unresolved issues, or problems
that would benefit from input from others. In your proposal, please
include a short description of the topic, what you would like to
discuss, and what kind of feedback or collaboration would help move the
work forward.

Allocated time per session is expected to be between 15 and 30 minutes.

Please submit proposals through the LPC 2026 abstracts page by August 7:

        https://lpc.events/event/20/abstracts/

Linux Plumbers Conference 2026 will be a hybrid event. While in-person
presentation is preferred to help keep the sessions smooth and
interactive, remote presentation will also be available.

We are looking forward to your proposals and to seeing you in Prague.

[0] https://lpc.events/event/20/contributions/2332/

Thanks,
Containers & Checkpoint/Restart Microconference Team

^ permalink raw reply

* Re: [PATCH v4 2/2] ima: measure buffer sent to securityfs policy file
From: Mimi Zohar @ 2026-06-25  1:05 UTC (permalink / raw)
  To: Enrico Bravi, linux-integrity, dmitry.kasatkin, roberto.sassu
  Cc: eric.snowberg
In-Reply-To: <20260617155832.434517-3-enrico.bravi@polito.it>

The Subject line describes "how", not "what". Consider renaming it to "ima:
measure userspace policy writes before parsing".

On Wed, 2026-06-17 at 17:58 +0200, Enrico Bravi wrote:
> When a signed policy is not mandatory, it is possible to write the IMA
> policy directly on the corresponding securityfs file:

When a signed policy is not mandatory, userspace can write IMA policy rules
directly to the securityfs policy file:
> 
> echo -e "measure func=BPRM_CHECK mask=MAY_EXEC\n" \
>         "audit func=BPRM_CHECK mask=MAY_EXEC\n" \
>      > /sys/kernel/security/ima/policy
> 
> or by cat'ing the entire IMA custom policy file:
> 
> cat ima-policy-file > /sys/kernel/security/ima/policy

Because these rules originate from userspace and cross the userspace/kernel
trust boundary, measure the raw write buffer before parsing.

> 
> Add input buffer measurement, regardless of whether the new policy
> will be accepted or not, that can be caught when
> 'measure func=POLICY_CHECK' is enabled (e.g., ima_policy=tcb). The
> measurement template is forced to ima-buf.

> This follows the "measure & load" paradigm, exposing potential bugs in
> the policy code and detecting attempts to corrupt IMA. It also completes
> the POLICY_CHECK hook, which already measures partial policy load by file.

> 
> To verify the template data hash value, convert the buffer policy data
> to binary:
> grep "ima_policy_written" \
> 	/sys/kernel/security/integrity/ima/ascii_runtime_measurements | \
> 	tail -1 | cut -d' ' -f 6 | xxd -r -p | sha256sum
> 
> Suggested-by: Roberto Sassu <roberto.sassu@huawei.com>
> Signed-off-by: Enrico Bravi <enrico.bravi@polito.it>
> ---
>  security/integrity/ima/ima.h        |  1 +
>  security/integrity/ima/ima_fs.c     |  1 +
>  security/integrity/ima/ima_main.c   | 19 +++++++++++++++++++
>  security/integrity/ima/ima_policy.c |  3 +++
>  4 files changed, 24 insertions(+)
> 
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index befa221716e5..d477fc06821f 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -455,6 +455,7 @@ void *ima_policy_next(struct seq_file *m, void *v, loff_t *pos);
>  void ima_policy_stop(struct seq_file *m, void *v);
>  int ima_policy_show(struct seq_file *m, void *v);
>  void ima_measure_loaded_policy(void);
> +int ima_measure_policy_buf(const char *buf, size_t buf_len);
>  
>  /* Appraise integrity measurements */
>  #define IMA_APPRAISE_ENFORCE	0x01
> diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c
> index 65e7812c702f..a277c9135944 100644
> --- a/security/integrity/ima/ima_fs.c
> +++ b/security/integrity/ima/ima_fs.c
> @@ -356,6 +356,7 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf,
>  				    1, 0);
>  		result = -EACCES;
>  	} else {
> +		ima_measure_policy_buf(data, datalen);

Should failure to measure the input policy rules be audited?

>  		result = ima_parse_add_rule(data);
>  	}
>  	mutex_unlock(&ima_write_mutex);
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 5cea53fc36df..599495304712 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -1221,6 +1221,25 @@ int ima_measure_critical_data(const char *event_label,
>  }
>  EXPORT_SYMBOL_GPL(ima_measure_critical_data);
>  
> +/**
> + * ima_measure_policy_buf - Measure the policy write buffer

Consider renaming this function to ima_measure_policy_input(), which parallels
the function ima_measure_loaded_policy() in the first patch.

Mimi

> + * @buf: pointer to the buffer containing the policy write data
> + * @buf_len: size of the buffer
> + *
> + * Measure the buffer sent to the IMA policy securityfs file.
> + *
> + * Return 0 on success, a negative value otherwise.
> + */
> +int ima_measure_policy_buf(const char *buf, size_t buf_len)
> +{
> +	if (!buf || !buf_len)
> +		return -EINVAL;
> +
> +	return process_buffer_measurement(&nop_mnt_idmap, NULL, buf, buf_len,
> +					  "ima_policy_written", POLICY_CHECK, 0,
> +					  NULL, false, NULL, 0);
> +}
> +
>  #ifdef CONFIG_INTEGRITY_ASYMMETRIC_KEYS
>  
>  /**

^ permalink raw reply

* Re: [PATCH v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: David Windsor @ 2026-06-24 21:22 UTC (permalink / raw)
  To: Paul Moore
  Cc: viro, brauner, jack, ast, daniel, john.fastabend, andrii, eddyz87,
	memxor, martin.lau, song, yonghong.song, jolsa, emil, kpsingh,
	mattbobrowski, jmorris, serge, zohar, roberto.sassu,
	dmitry.kasatkin, eric.snowberg, stephen.smalley.work, omosnace,
	casey, shuah, linux-kernel, linux-fsdevel, bpf,
	linux-security-module, linux-integrity, selinux, linux-kselftest
In-Reply-To: <75d39fd9847cca915d704235264ab474@paul-moore.com>

On Tue, Jun 23, 2026 at 8:12 PM Paul Moore <paul@paul-moore.com> wrote:
>
> I have a few specific comments below, inline with the patch, but I wanted
> to make some general comments too.
>
> The kfunc additions really don't belong in the VFS kfunc file, please
> create a LSM kfunc file (call it security/bpf_lsm_kfuncs.c) and add the
> kfunc code to this new file.
>

Makes sense. I will also do similarly for the selftests.

> While moving the kfunc additions to a LSM kfunc file does sort of convert
> the VFS changes into LSM changes, Christian's comment about splitting
> this patch two patches, one with the LSM hook changes and one with the
> BPF additions, is still reasonable and a good suggestion.  I would still
> CC the VFS folks on these patches and I would encourage reviews from the
> VFS folks as there is a VFS component here, albeit a somewhat small one.
>

v4 will contain 3 patches: one to introduce struct lsm_xattrs, next to
introduce the kfunc, and finally the selftests.

> > +
> > +static int __bpf_init_inode_xattr(struct xattr_ctx *xattr_ctx,
> > +                               const char *name__str,
> > +                               const struct bpf_dynptr *value_p)
> > +{
> > +     struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
> > +     size_t name_len;
> > +     void *xattr_value;
> > +     struct xattr *xattr;
> > +     struct xattr *xattrs;
> > +     int *xattr_count;
> > +     const void *value;
> > +     u32 value_len;
> > +
> > +     if (!xattr_ctx || !name__str)
> > +             return -EINVAL;
> > +
> > +     xattrs = xattr_ctx->xattrs;
> > +     xattr_count = xattr_ctx->xattr_count;
>
> I'm not sure why the "xattrs" and "xattrs_count" local variables are
> necessary, especially since they only appear to be used in the sanity
> check below.  I would suggest just using the values in the struct
> directly.
>

Leftover from the previous implementation, will fix.

> > +/**
> > + * bpf_init_inode_xattr - set an xattr on a new inode from inode_init_security
> > + * @xattr_ctx: inode_init_security xattr state from the hook context
> > + * @name__str: xattr name (e.g., "bpf.file_label")
> > + * @value_p: dynptr containing the xattr value
> > + *
> > + * Only callable from lsm/inode_init_security programs.
> > + *
> > + * Return: 0 on success, negative error on failure.
> > + */
> > +__bpf_kfunc int bpf_init_inode_xattr(struct xattr_ctx *xattr_ctx,
> > +                                  const char *name__str,
> > +                                  const struct bpf_dynptr *value_p)
> > +{
> > +     return __bpf_init_inode_xattr(xattr_ctx, name__str, value_p);
> > +}
>
> I'm sure there is a reason why you split the code out into
> __bpf_init_inode_xattr() as opposed to just putting it directly in this
> kfunc, can you help me understand?

Not sure, perhaps prior convention, or something with the verifier
perhaps. I've removed it in -v4 and everything works.

> > diff --git a/include/linux/security.h b/include/linux/security.h
> > index 153e9043058f..1f8e84e7dd7e 100644
> > --- a/include/linux/security.h
> > +++ b/include/linux/security.h
> > @@ -68,6 +68,11 @@ struct watch;
> >  struct watch_notification;
> >  struct lsm_ctx;
> >
> > +struct xattr_ctx {
> > +     struct xattr *xattrs;
> > +     int *xattr_count;
> > +};
>
> I see the bots already pointed this out, and you acknowledged it, but
> since I'm looking at this I felt obliged to remind you once again about
> the rename to "struct lsm_xattrs" :)
>

Yeah, sorry about that. =)

> Also, looking at this closer, is there a reason why the "xattr_count"
> field is an integer pointer and not just an integer?  We're passing
> the entire struct by reference to the individual LSMs so we shouldn't
> need this to get an updated count in the caller and having it as a
> regular integer should simplify things slightly (you could also
> make it an unsigned int while you are it).
>

Copy/paste from v2. Will change xattr_count's type to unsigned int.

> > --- a/kernel/bpf/trampoline.c
> > +++ b/kernel/bpf/trampoline.c
> > @@ -859,6 +859,9 @@ static int bpf_trampoline_add_prog(struct bpf_trampoline *tr,
> >       }
> >       if (cnt >= BPF_MAX_TRAMP_LINKS)
> >               return -E2BIG;
> > +     if (node->link->prog->aux->attach_limit &&
> > +         tr->progs_cnt[kind] >= node->link->prog->aux->attach_limit)
> > +             return -E2BIG;
>
> Re: Alexei's comments about this - if you look back at my previous
> comments, my concern was around BPF LSMs using too many slots in the
> xattr array and causing issues.  If the BPF folks want to do that check
> in the kfunc located in the LSM framework I'm okay with that; the
> important part is that the BPF LSMs don't use more space than they
> previously requested.
>

Ack, will remove this attach-time check.

> > diff --git a/security/security.c b/security/security.c
> > index 71aea8fdf014..8f82a1352356 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -1334,6 +1334,7 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
> >  {
> >       struct lsm_static_call *scall;
> >       struct xattr *new_xattrs = NULL;
> > +     struct xattr_ctx xattr_ctx;
> >       int ret = -EOPNOTSUPP, xattr_count = 0;
>
> Since we have the xattr array/pointer and count in the new "lsm_xattrs"
> struct, I think we can remove the "new_xattrs" and "xattr_count" local
> variables in favor of the fields in the new struct.
>

Thanks! These will be eliminated in v4.

Best,
David

^ permalink raw reply

* Re: [PATCH v4 1/2] ima: measure loaded policy after write on securityfs policy file
From: Mimi Zohar @ 2026-06-24 20:35 UTC (permalink / raw)
  To: Enrico Bravi, linux-integrity, dmitry.kasatkin, roberto.sassu
  Cc: eric.snowberg
In-Reply-To: <20260617155832.434517-2-enrico.bravi@polito.it>

The Subject line needs to be written from a higher perspective.  It describes
"how", not "what".
Consider using "ima: add critical data measurement for loaded policy".

On Wed, 2026-06-17 at 17:58 +0200, Enrico Bravi wrote:
> IMA policy can be written multiple times in the securityfs policy file
> at runtime if CONFIG_IMA_WRITE_POLICY=y. When IMA_APPRAISE_POLICY is
> required, the policy needs to be signed to be loaded, writing the absolute
> path of the file containing the new policy:
> 
> echo /path/of/custom_ima_policy > /sys/kernel/security/ima/policy
> 
> When this is not required, policy can be written directly, rule by rule:
> 
> echo -e "measure func=BPRM_CHECK mask=MAY_EXEC\n" \
>         "audit func=BPRM_CHECK mask=MAY_EXEC\n" \
>      > /sys/kernel/security/ima/policy
> 
> In this case, a new policy can be loaded without being measured or
> appraised.
> 
> Add a new critical data record to measure the textual policy
> representation when it becomes effective. Include in the
> architecture-specific policy the new critical data record only when it
> is not mandatory to load a signed policy. Additionally, enable the
> policy serialization code even when CONFIG_IMA_READ_POLICY=n.
> 
> To verify the template data hash value, convert the buffer policy data
> to binary:
> grep "ima_policy_loaded" \
>         /sys/kernel/security/integrity/ima/ascii_runtime_measurements | \
>         tail -1 | cut -d' ' -f 6 | xxd -r -p | sha256sum
> 
> Signed-off-by: Enrico Bravi <enrico.bravi@polito.it>

Thank you for making the changes.

[ ... ]

> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index f7f940a76922..0a70d10da70a 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c

> @@ -2379,3 +2378,70 @@ bool ima_appraise_signature(enum kernel_read_file_id id)
>  	return found;
>  }
>  #endif /* CONFIG_IMA_APPRAISE && CONFIG_INTEGRITY_TRUSTED_KEYRING */
> +
> +/**
> +* ima_measure_loaded_policy - measure the active IMA policy ruleset
> +*
> +* Must be called with ima_write_mutex held, as it performs two
> +* separate RCU read passes over ima_rules and relies on the mutex
> +* to prevent concurrent policy updates between them.
> +*/
> +void ima_measure_loaded_policy(void)
> +{
> +	const char *event_name = "ima_policy_loaded";
> +	const char *op = "measure_loaded_ima_policy";
> +	struct ima_rule_entry *rule_entry;
> +	struct list_head *ima_rules_tmp;
> +	struct seq_file file;
> +	int result = -ENOMEM;
> +	size_t file_len = 0;
> +	char rule[512];
> +
> +	/* calculate IMA policy rules memory size */
> +	file.buf = rule;
> +	file.read_pos = 0;
> +	file.size = 512;
> +	file.count = 0;
> +
> +	lockdep_assert_held(&ima_write_mutex);
> +
> +	rcu_read_lock();
> +	ima_rules_tmp = rcu_dereference(ima_rules);
> +	list_for_each_entry_rcu(rule_entry, ima_rules_tmp, list) {
> +		ima_policy_show(&file, rule_entry);
> +		if (seq_has_overflowed(&file)) {
> +			result = -E2BIG;
> +			integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, event_name,
> +					    op, "rule_length", result, 1);
> +			return;

On failure the new IMA policy will not be measured. Instead of hard coding the
buffer to 512, define a file static global variable to keep track of the maximum
policy rule size.  ima_parse_add_rule() already returns the policy rule length.
Before returning update the max policy rule size variable as necessary.

Here in ima_measure_loaded_policy() allocate/free the buffer.

Missing rcu_read_unlock() before returning.

thanks,

Mimi

> +		}
> +
> +		file_len += file.count;
> +		file.count = 0;
> +	}
> +	rcu_read_unlock();
> +
> +	/* copy IMA policy rules to a buffer for measuring */
> +	file.buf = vmalloc(file_len);
> +	if (!file.buf) {
> +		integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, event_name,
> +				    op, "ENOMEM", result, 1);
> +		return;
> +	}
> +
> +	file.read_pos = 0;
> +	file.size = file_len;
> +	file.count = 0;
> +
> +	rcu_read_lock();
> +	ima_rules_tmp = rcu_dereference(ima_rules);
> +	list_for_each_entry_rcu(rule_entry, ima_rules_tmp, list) {
> +		ima_policy_show(&file, rule_entry);
> +	}
> +	rcu_read_unlock();
> +
> +	ima_measure_critical_data("ima_policy", event_name, file.buf,
> +				  file.count, false, NULL, 0);
> +
> +	vfree(file.buf);
> +}

^ permalink raw reply

* Kernsec sales
From: Eric Young @ 2026-06-24 13:40 UTC (permalink / raw)
  To: linux-integrity

Hi,

I noticed your focus on the Linux kernel security subsystem and the resources you provide for developers and users.

Managing detailed technical information and supporting user communication can be time consuming without the right tools.

We have helped teams automate client interactions and scheduling in complex technical environments without adding extra resources.

Would you be open to a brief conversation to explore if this could help streamline your community engagement? 


Eric
422 Richards St, Suite 170. Vancouver, BC V6B 2Z4
P.S. Please let me know if you don't want to hear from me again

^ permalink raw reply

* Re: [PATCH v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic  inode labeling
From: Paul Moore @ 2026-06-24  0:12 UTC (permalink / raw)
  To: David Windsor, viro, brauner, jack, ast, daniel, john.fastabend,
	andrii, eddyz87, memxor, martin.lau, song, yonghong.song, jolsa,
	emil, kpsingh, mattbobrowski, jmorris, serge, zohar,
	roberto.sassu, dmitry.kasatkin, eric.snowberg,
	stephen.smalley.work, omosnace, casey, shuah
  Cc: linux-kernel, linux-fsdevel, bpf, linux-security-module,
	linux-integrity, selinux, linux-kselftest, David Windsor
In-Reply-To: <20260618203411.73917-2-dwindsor@gmail.com>

On Jun 18, 2026 David Windsor <dwindsor@gmail.com> wrote:
> 
> Add bpf_init_inode_xattr() kfunc for BPF LSM programs to atomically set
> xattrs via the inode_init_security hook using lsm_get_xattr_slot().
> 
> The inode_init_security hook previously took the xattr array and count
> as two separate output parameters (struct xattr *xattrs, int
> *xattr_count), which BPF programs cannot write to. Pass the xattr state
> as a single context object (struct xattr_ctx) instead, and have
> bpf_init_inode_xattr() take that context directly. Update the existing
> in-tree callers of inode_init_security to take and forward the new
> xattr_ctx.
> 
> A previous attempt [1] required a kmalloc string output protocol for
> the xattr name. Since commit 6bcdfd2cac55 ("security: Allow all LSMs to
> provide xattrs for inode_init_security hook") [2], the xattr name is no
> longer allocated; it is a static constant.
> 
> Because we rely on the hook-specific ctx layout, the kfunc is
> restricted to lsm/inode_init_security. Restrict the xattr names that
> may be set via this kfunc to the bpf.* namespace.
> 
> Link: https://kernsec.org/pipermail/linux-security-module-archive/2022-October/034878.html [1]
> Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6bcdfd2cac55 [2]
> Suggested-by: Song Liu <song@kernel.org>
> Signed-off-by: David Windsor <dwindsor@gmail.com>
> ---
>  fs/bpf_fs_kfuncs.c                | 106 +++++++++++++++++++++++++++++-
>  include/linux/bpf.h               |   1 +
>  include/linux/bpf_lsm.h           |   3 +
>  include/linux/evm.h               |   9 +--
>  include/linux/lsm_hook_defs.h     |   4 +-
>  include/linux/lsm_hooks.h         |  16 ++---
>  include/linux/security.h          |   5 ++
>  kernel/bpf/bpf_lsm.c              |  10 +++
>  kernel/bpf/trampoline.c           |   3 +
>  security/bpf/hooks.c              |   1 +
>  security/integrity/evm/evm_main.c |   8 ++-
>  security/security.c               |   7 +-
>  security/selinux/hooks.c          |   4 +-
>  security/smack/smack_lsm.c        |  27 ++++----
>  14 files changed, 166 insertions(+), 38 deletions(-)

I have a few specific comments below, inline with the patch, but I wanted
to make some general comments too.

The kfunc additions really don't belong in the VFS kfunc file, please
create a LSM kfunc file (call it security/bpf_lsm_kfuncs.c) and add the
kfunc code to this new file.

While moving the kfunc additions to a LSM kfunc file does sort of convert
the VFS changes into LSM changes, Christian's comment about splitting
this patch two patches, one with the LSM hook changes and one with the
BPF additions, is still reasonable and a good suggestion.  I would still
CC the VFS folks on these patches and I would encourage reviews from the
VFS folks as there is a VFS component here, albeit a somewhat small one.

> diff --git a/fs/bpf_fs_kfuncs.c b/fs/bpf_fs_kfuncs.c
> index 768aca2dc0f0..7abc3f3d1a67 100644
> --- a/fs/bpf_fs_kfuncs.c
> +++ b/fs/bpf_fs_kfuncs.c
> @@ -10,6 +10,7 @@
>  #include <linux/fsnotify.h>
>  #include <linux/file.h>
>  #include <linux/kernfs.h>
> +#include <linux/lsm_hooks.h>
>  #include <linux/mm.h>
>  #include <linux/xattr.h>
>  
> @@ -374,6 +375,97 @@ __bpf_kfunc struct inode *bpf_real_inode(struct dentry *dentry)
>  	return d_real_inode(dentry);
>  }
>  
> +static int bpf_xattrs_used(const struct xattr_ctx *ctx)
> +{
> +	const size_t prefix_len = sizeof(XATTR_BPF_LSM_SUFFIX) - 1;
> +	int i, n = 0;
> +
> +	for (i = 0; i < *ctx->xattr_count; i++) {
> +		const char *name = ctx->xattrs[i].name;
> +
> +		if (name && !strncmp(name, XATTR_BPF_LSM_SUFFIX, prefix_len))
> +			n++;
> +	}
> +	return n;
> +}
> +
> +static int __bpf_init_inode_xattr(struct xattr_ctx *xattr_ctx,
> +				  const char *name__str,
> +				  const struct bpf_dynptr *value_p)
> +{
> +	struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
> +	size_t name_len;
> +	void *xattr_value;
> +	struct xattr *xattr;
> +	struct xattr *xattrs;
> +	int *xattr_count;
> +	const void *value;
> +	u32 value_len;
> +
> +	if (!xattr_ctx || !name__str)
> +		return -EINVAL;
> +
> +	xattrs = xattr_ctx->xattrs;
> +	xattr_count = xattr_ctx->xattr_count;

I'm not sure why the "xattrs" and "xattrs_count" local variables are
necessary, especially since they only appear to be used in the sanity
check below.  I would suggest just using the values in the struct
directly.

> +	if (!xattrs || !xattr_count)
> +		return -EINVAL;
> +	if (bpf_xattrs_used(xattr_ctx) >= BPF_LSM_INODE_INIT_XATTRS)
> +		return -ENOSPC;
> +
> +	name_len = strlen(name__str);
> +	if (name_len == 0 || name_len > XATTR_NAME_MAX)
> +		return -EINVAL;
> +	if (strncmp(name__str, XATTR_BPF_LSM_SUFFIX,
> +		    sizeof(XATTR_BPF_LSM_SUFFIX) - 1))
> +		return -EPERM;
> +
> +	value_len = __bpf_dynptr_size(value_ptr);
> +	if (value_len == 0 || value_len > XATTR_SIZE_MAX)
> +		return -EINVAL;
> +
> +	value = __bpf_dynptr_data(value_ptr, value_len);
> +	if (!value)
> +		return -EINVAL;
> +
> +	/* Combine xattr value + name into one allocation. */
> +	xattr_value = kmalloc(value_len + name_len + 1, GFP_KERNEL);
> +	if (!xattr_value)
> +		return -ENOMEM;
> +
> +	memcpy(xattr_value, value, value_len);
> +	memcpy(xattr_value + value_len, name__str, name_len);
> +	((char *)xattr_value)[value_len + name_len] = '\0';
> +
> +	xattr = lsm_get_xattr_slot(xattr_ctx);
> +	if (!xattr) {
> +		kfree(xattr_value);
> +		return -ENOSPC;
> +	}
> +
> +	xattr->value = xattr_value;
> +	xattr->name = (const char *)xattr_value + value_len;
> +	xattr->value_len = value_len;
> +
> +	return 0;
> +}
> +
> +/**
> + * bpf_init_inode_xattr - set an xattr on a new inode from inode_init_security
> + * @xattr_ctx: inode_init_security xattr state from the hook context
> + * @name__str: xattr name (e.g., "bpf.file_label")
> + * @value_p: dynptr containing the xattr value
> + *
> + * Only callable from lsm/inode_init_security programs.
> + *
> + * Return: 0 on success, negative error on failure.
> + */
> +__bpf_kfunc int bpf_init_inode_xattr(struct xattr_ctx *xattr_ctx,
> +				     const char *name__str,
> +				     const struct bpf_dynptr *value_p)
> +{
> +	return __bpf_init_inode_xattr(xattr_ctx, name__str, value_p);
> +}

I'm sure there is a reason why you split the code out into
__bpf_init_inode_xattr() as opposed to just putting it directly in this
kfunc, can you help me understand?

> diff --git a/include/linux/security.h b/include/linux/security.h
> index 153e9043058f..1f8e84e7dd7e 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -68,6 +68,11 @@ struct watch;
>  struct watch_notification;
>  struct lsm_ctx;
>  
> +struct xattr_ctx {
> +	struct xattr *xattrs;
> +	int *xattr_count;
> +};

I see the bots already pointed this out, and you acknowledged it, but
since I'm looking at this I felt obliged to remind you once again about
the rename to "struct lsm_xattrs" :)

Also, looking at this closer, is there a reason why the "xattr_count"
field is an integer pointer and not just an integer?  We're passing
the entire struct by reference to the individual LSMs so we shouldn't
need this to get an updated count in the caller and having it as a
regular integer should simplify things slightly (you could also
make it an unsigned int while you are it).
 
> @@ -315,6 +324,7 @@ BTF_ID(func, bpf_lsm_inode_create)
>  BTF_ID(func, bpf_lsm_inode_free_security)
>  BTF_ID(func, bpf_lsm_inode_getattr)
>  BTF_ID(func, bpf_lsm_inode_getxattr)
> +BTF_ID(func, bpf_lsm_inode_init_security)
>  BTF_ID(func, bpf_lsm_inode_mknod)
>  BTF_ID(func, bpf_lsm_inode_need_killpriv)
>  BTF_ID(func, bpf_lsm_inode_post_setxattr)
> diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> index 1a721fc4bef5..b41b02173e24 100644
> --- a/kernel/bpf/trampoline.c
> +++ b/kernel/bpf/trampoline.c
> @@ -859,6 +859,9 @@ static int bpf_trampoline_add_prog(struct bpf_trampoline *tr,
>  	}
>  	if (cnt >= BPF_MAX_TRAMP_LINKS)
>  		return -E2BIG;
> +	if (node->link->prog->aux->attach_limit &&
> +	    tr->progs_cnt[kind] >= node->link->prog->aux->attach_limit)
> +		return -E2BIG;

Re: Alexei's comments about this - if you look back at my previous
comments, my concern was around BPF LSMs using too many slots in the
xattr array and causing issues.  If the BPF folks want to do that check
in the kfunc located in the LSM framework I'm okay with that; the
important part is that the BPF LSMs don't use more space than they
previously requested.

> diff --git a/security/security.c b/security/security.c
> index 71aea8fdf014..8f82a1352356 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -1334,6 +1334,7 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
>  {
>  	struct lsm_static_call *scall;
>  	struct xattr *new_xattrs = NULL;
> +	struct xattr_ctx xattr_ctx;
>  	int ret = -EOPNOTSUPP, xattr_count = 0;

Since we have the xattr array/pointer and count in the new "lsm_xattrs"
struct, I think we can remove the "new_xattrs" and "xattr_count" local
variables in favor of the fields in the new struct.

>  	if (unlikely(IS_PRIVATE(inode)))
> @@ -1349,10 +1350,12 @@ int security_inode_init_security(struct inode *inode, struct inode *dir,
>  		if (!new_xattrs)
>  			return -ENOMEM;
>  	}
> +	xattr_ctx.xattrs = new_xattrs;
> +	xattr_ctx.xattr_count = &xattr_count;
>  
>  	lsm_for_each_hook(scall, inode_init_security) {
> -		ret = scall->hl->hook.inode_init_security(inode, dir, qstr, new_xattrs,
> -						  &xattr_count);
> +		ret = scall->hl->hook.inode_init_security(inode, dir, qstr,
> +							  &xattr_ctx);
>  		if (ret && ret != -EOPNOTSUPP)
>  			goto out;
>  		/*

--
paul-moore.com

^ permalink raw reply

* Re: [GIT PULL] TPM DEVICE DRIVER: for-next-tpm-7.2-rc1-fixed
From: pr-tracker-bot @ 2026-06-23 15:40 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: Linus Torvalds, Peter Huewe, Jason Gunthorpe, David Howells,
	keyrings, linux-integrity, linux-kernel
In-Reply-To: <ajlVR8okpQirKw5-@kernel.org>

The pull request you sent on Mon, 22 Jun 2026 18:31:19 +0300:

> git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git tags/for-next-tpm-7.2-rc1-fixed

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/16b2087efdddd0bf042accdbdcc8eedc21bf9227

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

^ permalink raw reply

* Re: [PATCH bpf-next v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: David Windsor @ 2026-06-23  4:01 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Alexander Viro, Christian Brauner, Jan Kara, Alexei Starovoitov,
	Daniel Borkmann, John Fastabend, Andrii Nakryiko, Eduard,
	Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu,
	Yonghong Song, Jiri Olsa, Emil Tsalapatis, KP Singh,
	Matt Bobrowski, Paul Moore, James Morris, Serge E . Hallyn,
	Mimi Zohar, Roberto Sassu, dmitry.kasatkin, eric.snowberg,
	Stephen Smalley, Ondrej Mosnacek, Casey Schaufler, Shuah Khan,
	LKML, Linux-Fsdevel, bpf, LSM List, linux-integrity, selinux,
	open list:KERNEL SELFTEST FRAMEWORK
In-Reply-To: <CAADnVQJsdrL2RjxM4UE1WyWrT9KsprFP+=xLHRtFhUSccDqQcg@mail.gmail.com>

On Mon, Jun 22, 2026 at 11:59 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> >
> > > > diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> > > > index 1a721fc4bef5..b41b02173e24 100644
> > > > --- a/kernel/bpf/trampoline.c
> > > > +++ b/kernel/bpf/trampoline.c
> > > > @@ -859,6 +859,9 @@ static int bpf_trampoline_add_prog(struct bpf_trampoline *tr,
> > > >       }
> > > >       if (cnt >= BPF_MAX_TRAMP_LINKS)
> > > >               return -E2BIG;
> > > > +     if (node->link->prog->aux->attach_limit &&
> > > > +         tr->progs_cnt[kind] >= node->link->prog->aux->attach_limit)
> > > > +             return -E2BIG;
> > >
> > > No need. The check inside kfunc is enough.
> > >
> >
> > Paul wanted this check because it occurs at bpf prog attach time,
> > whereas the one in the kfunc is at inode creation time.
>
> Sorry, we're not adding redundant code to the verifier.

Thanks, will send v4 soon.

^ permalink raw reply

* Re: [PATCH bpf-next v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: Alexei Starovoitov @ 2026-06-23  3:59 UTC (permalink / raw)
  To: David Windsor
  Cc: Alexander Viro, Christian Brauner, Jan Kara, Alexei Starovoitov,
	Daniel Borkmann, John Fastabend, Andrii Nakryiko, Eduard,
	Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu,
	Yonghong Song, Jiri Olsa, Emil Tsalapatis, KP Singh,
	Matt Bobrowski, Paul Moore, James Morris, Serge E . Hallyn,
	Mimi Zohar, Roberto Sassu, dmitry.kasatkin, eric.snowberg,
	Stephen Smalley, Ondrej Mosnacek, Casey Schaufler, Shuah Khan,
	LKML, Linux-Fsdevel, bpf, LSM List, linux-integrity, selinux,
	open list:KERNEL SELFTEST FRAMEWORK
In-Reply-To: <CAEXv5_jVXS4JoExcd71YkXEE2WXPJ0_9STO-uCwgNF+Eia_h5w@mail.gmail.com>

On Mon, Jun 22, 2026 at 8:49 PM David Windsor <dwindsor@gmail.com> wrote:
>
> On Mon, Jun 22, 2026 at 7:57 PM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > On Thu Jun 18, 2026 at 1:34 PM PDT, David Windsor wrote:
> > > +
> > > +static int __bpf_init_inode_xattr(struct xattr_ctx *xattr_ctx,
> > > +                               const char *name__str,
> > > +                               const struct bpf_dynptr *value_p)
> > > +{
> > > +     struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
> > > +     size_t name_len;
> > > +     void *xattr_value;
> > > +     struct xattr *xattr;
> > > +     struct xattr *xattrs;
> > > +     int *xattr_count;
> > > +     const void *value;
> > > +     u32 value_len;
> > > +
> > > +     if (!xattr_ctx || !name__str)
> > > +             return -EINVAL;
> > > +
> > > +     xattrs = xattr_ctx->xattrs;
> > > +     xattr_count = xattr_ctx->xattr_count;
> > > +     if (!xattrs || !xattr_count)
> > > +             return -EINVAL;
> > > +     if (bpf_xattrs_used(xattr_ctx) >= BPF_LSM_INODE_INIT_XATTRS)
> > > +             return -ENOSPC;
> >
> > This check is good to have, but it's enough. No need to duplicate it.
> > More below.
> >
>
> > > +
> > >  static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id)
> > >  {
> > >       if (!btf_id_set8_contains(&bpf_fs_kfunc_set_ids, kfunc_id) ||
> > > -         prog->type == BPF_PROG_TYPE_LSM)
> > > +         prog->type == BPF_PROG_TYPE_LSM) {
> > > +             /* bpf_init_inode_xattr only attaches to inode_init_security. */
> > > +             if (kfunc_id == bpf_init_inode_xattr_btf_ids[0] &&
> > > +                 prog->aux->attach_btf_id != bpf_lsm_inode_init_security_btf_ids[0])
> > > +                     return -EACCES;
> >
> > This is unnecessary. Only one hook will have xattr_ctx type.
> > The normal verifier type enforcement will do its work.
> >
>
> Good point, thanks.
>
> > > diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> > > index 1a721fc4bef5..b41b02173e24 100644
> > > --- a/kernel/bpf/trampoline.c
> > > +++ b/kernel/bpf/trampoline.c
> > > @@ -859,6 +859,9 @@ static int bpf_trampoline_add_prog(struct bpf_trampoline *tr,
> > >       }
> > >       if (cnt >= BPF_MAX_TRAMP_LINKS)
> > >               return -E2BIG;
> > > +     if (node->link->prog->aux->attach_limit &&
> > > +         tr->progs_cnt[kind] >= node->link->prog->aux->attach_limit)
> > > +             return -E2BIG;
> >
> > No need. The check inside kfunc is enough.
> >
>
> Paul wanted this check because it occurs at bpf prog attach time,
> whereas the one in the kfunc is at inode creation time.

Sorry, we're not adding redundant code to the verifier.

^ permalink raw reply

* Re: [PATCH bpf-next v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: David Windsor @ 2026-06-23  3:49 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: viro, brauner, jack, ast, daniel, john.fastabend, andrii, eddyz87,
	memxor, martin.lau, song, yonghong.song, jolsa, emil, kpsingh,
	mattbobrowski, paul, jmorris, serge, zohar, roberto.sassu,
	dmitry.kasatkin, eric.snowberg, stephen.smalley.work, omosnace,
	casey, shuah, linux-kernel, linux-fsdevel, bpf,
	linux-security-module, linux-integrity, selinux, linux-kselftest
In-Reply-To: <DJFZGYZFMN73.1799LMXW49WZO@gmail.com>

On Mon, Jun 22, 2026 at 7:57 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Thu Jun 18, 2026 at 1:34 PM PDT, David Windsor wrote:
> > +
> > +static int __bpf_init_inode_xattr(struct xattr_ctx *xattr_ctx,
> > +                               const char *name__str,
> > +                               const struct bpf_dynptr *value_p)
> > +{
> > +     struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
> > +     size_t name_len;
> > +     void *xattr_value;
> > +     struct xattr *xattr;
> > +     struct xattr *xattrs;
> > +     int *xattr_count;
> > +     const void *value;
> > +     u32 value_len;
> > +
> > +     if (!xattr_ctx || !name__str)
> > +             return -EINVAL;
> > +
> > +     xattrs = xattr_ctx->xattrs;
> > +     xattr_count = xattr_ctx->xattr_count;
> > +     if (!xattrs || !xattr_count)
> > +             return -EINVAL;
> > +     if (bpf_xattrs_used(xattr_ctx) >= BPF_LSM_INODE_INIT_XATTRS)
> > +             return -ENOSPC;
>
> This check is good to have, but it's enough. No need to duplicate it.
> More below.
>

> > +
> >  static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id)
> >  {
> >       if (!btf_id_set8_contains(&bpf_fs_kfunc_set_ids, kfunc_id) ||
> > -         prog->type == BPF_PROG_TYPE_LSM)
> > +         prog->type == BPF_PROG_TYPE_LSM) {
> > +             /* bpf_init_inode_xattr only attaches to inode_init_security. */
> > +             if (kfunc_id == bpf_init_inode_xattr_btf_ids[0] &&
> > +                 prog->aux->attach_btf_id != bpf_lsm_inode_init_security_btf_ids[0])
> > +                     return -EACCES;
>
> This is unnecessary. Only one hook will have xattr_ctx type.
> The normal verifier type enforcement will do its work.
>

Good point, thanks.

> > diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> > index 1a721fc4bef5..b41b02173e24 100644
> > --- a/kernel/bpf/trampoline.c
> > +++ b/kernel/bpf/trampoline.c
> > @@ -859,6 +859,9 @@ static int bpf_trampoline_add_prog(struct bpf_trampoline *tr,
> >       }
> >       if (cnt >= BPF_MAX_TRAMP_LINKS)
> >               return -E2BIG;
> > +     if (node->link->prog->aux->attach_limit &&
> > +         tr->progs_cnt[kind] >= node->link->prog->aux->attach_limit)
> > +             return -E2BIG;
>
> No need. The check inside kfunc is enough.
>

Paul wanted this check because it occurs at bpf prog attach time,
whereas the one in the kfunc is at inode creation time.


> >       if (!hlist_unhashed(&node->tramp_hlist))
> >               /* prog already linked */
> >               return -EBUSY;
> > diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c
> > index 40efde233f3a..d7c44c5c0e30 100644
> > --- a/security/bpf/hooks.c
> > +++ b/security/bpf/hooks.c
> > @@ -30,6 +30,7 @@ static int __init bpf_lsm_init(void)
> >
> >  struct lsm_blob_sizes bpf_lsm_blob_sizes __ro_after_init = {
> >       .lbs_inode = sizeof(struct bpf_storage_blob),
> > +     .lbs_xattr_count = BPF_LSM_INODE_INIT_XATTRS,
> >  };
> >
> >  DEFINE_LSM(bpf) = {
> > diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
> > index b59e3f121b8a..e0a05162accc 100644
> > --- a/security/integrity/evm/evm_main.c
> > +++ b/security/integrity/evm/evm_main.c
> > @@ -1062,14 +1062,16 @@ static int evm_inode_copy_up_xattr(struct dentry *src, const char *name)
> >   * evm_inode_init_security - initializes security.evm HMAC value
> >   */
> >  int evm_inode_init_security(struct inode *inode, struct inode *dir,
> > -                         const struct qstr *qstr, struct xattr *xattrs,
> > -                         int *xattr_count)
> > +                         const struct qstr *qstr,
> > +                         struct xattr_ctx *xattr_ctx)
>
> the rest looks good.
> Pls split the patch. Introduce xattr_ctx first across the LSMs.
> Then another patch with a new kfunc.
>
> pw-bot: cr

^ permalink raw reply

* Re: [PATCH bpf-next v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: Alexei Starovoitov @ 2026-06-22 23:57 UTC (permalink / raw)
  To: David Windsor, viro, brauner, jack, ast, daniel, john.fastabend,
	andrii, eddyz87, memxor, martin.lau, song, yonghong.song, jolsa,
	emil, kpsingh, mattbobrowski, paul, jmorris, serge, zohar,
	roberto.sassu, dmitry.kasatkin, eric.snowberg,
	stephen.smalley.work, omosnace, casey, shuah
  Cc: linux-kernel, linux-fsdevel, bpf, linux-security-module,
	linux-integrity, selinux, linux-kselftest
In-Reply-To: <20260618203411.73917-2-dwindsor@gmail.com>

On Thu Jun 18, 2026 at 1:34 PM PDT, David Windsor wrote:
> +
> +static int __bpf_init_inode_xattr(struct xattr_ctx *xattr_ctx,
> +				  const char *name__str,
> +				  const struct bpf_dynptr *value_p)
> +{
> +	struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p;
> +	size_t name_len;
> +	void *xattr_value;
> +	struct xattr *xattr;
> +	struct xattr *xattrs;
> +	int *xattr_count;
> +	const void *value;
> +	u32 value_len;
> +
> +	if (!xattr_ctx || !name__str)
> +		return -EINVAL;
> +
> +	xattrs = xattr_ctx->xattrs;
> +	xattr_count = xattr_ctx->xattr_count;
> +	if (!xattrs || !xattr_count)
> +		return -EINVAL;
> +	if (bpf_xattrs_used(xattr_ctx) >= BPF_LSM_INODE_INIT_XATTRS)
> +		return -ENOSPC;

This check is good to have, but it's enough. No need to duplicate it.
More below.

> +
> +	name_len = strlen(name__str);
> +	if (name_len == 0 || name_len > XATTR_NAME_MAX)
> +		return -EINVAL;
> +	if (strncmp(name__str, XATTR_BPF_LSM_SUFFIX,
> +		    sizeof(XATTR_BPF_LSM_SUFFIX) - 1))
> +		return -EPERM;
> +
> +	value_len = __bpf_dynptr_size(value_ptr);
> +	if (value_len == 0 || value_len > XATTR_SIZE_MAX)
> +		return -EINVAL;
> +
> +	value = __bpf_dynptr_data(value_ptr, value_len);
> +	if (!value)
> +		return -EINVAL;
> +
> +	/* Combine xattr value + name into one allocation. */
> +	xattr_value = kmalloc(value_len + name_len + 1, GFP_KERNEL);
> +	if (!xattr_value)
> +		return -ENOMEM;
> +
> +	memcpy(xattr_value, value, value_len);
> +	memcpy(xattr_value + value_len, name__str, name_len);
> +	((char *)xattr_value)[value_len + name_len] = '\0';
> +
> +	xattr = lsm_get_xattr_slot(xattr_ctx);
> +	if (!xattr) {
> +		kfree(xattr_value);
> +		return -ENOSPC;
> +	}
> +
> +	xattr->value = xattr_value;
> +	xattr->name = (const char *)xattr_value + value_len;
> +	xattr->value_len = value_len;
> +
> +	return 0;
> +}
> +
> +/**
> + * bpf_init_inode_xattr - set an xattr on a new inode from inode_init_security
> + * @xattr_ctx: inode_init_security xattr state from the hook context
> + * @name__str: xattr name (e.g., "bpf.file_label")
> + * @value_p: dynptr containing the xattr value
> + *
> + * Only callable from lsm/inode_init_security programs.
> + *
> + * Return: 0 on success, negative error on failure.
> + */
> +__bpf_kfunc int bpf_init_inode_xattr(struct xattr_ctx *xattr_ctx,
> +				     const char *name__str,
> +				     const struct bpf_dynptr *value_p)
> +{
> +	return __bpf_init_inode_xattr(xattr_ctx, name__str, value_p);
> +}
> +
>  __bpf_kfunc_end_defs();
>  
>  BTF_KFUNCS_START(bpf_fs_kfunc_set_ids)
> @@ -385,13 +477,25 @@ BTF_ID_FLAGS(func, bpf_get_file_xattr, KF_SLEEPABLE)
>  BTF_ID_FLAGS(func, bpf_set_dentry_xattr, KF_SLEEPABLE)
>  BTF_ID_FLAGS(func, bpf_remove_dentry_xattr, KF_SLEEPABLE)
>  BTF_ID_FLAGS(func, bpf_real_inode, KF_SLEEPABLE | KF_RET_NULL)
> +BTF_ID_FLAGS(func, bpf_init_inode_xattr, KF_SLEEPABLE)
>  BTF_KFUNCS_END(bpf_fs_kfunc_set_ids)
>  
> +BTF_ID_LIST(bpf_lsm_inode_init_security_btf_ids)
> +BTF_ID(func, bpf_lsm_inode_init_security)
> +
> +BTF_ID_LIST(bpf_init_inode_xattr_btf_ids)
> +BTF_ID(func, bpf_init_inode_xattr)
> +
>  static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id)
>  {
>  	if (!btf_id_set8_contains(&bpf_fs_kfunc_set_ids, kfunc_id) ||
> -	    prog->type == BPF_PROG_TYPE_LSM)
> +	    prog->type == BPF_PROG_TYPE_LSM) {
> +		/* bpf_init_inode_xattr only attaches to inode_init_security. */
> +		if (kfunc_id == bpf_init_inode_xattr_btf_ids[0] &&
> +		    prog->aux->attach_btf_id != bpf_lsm_inode_init_security_btf_ids[0])
> +			return -EACCES;

This is unnecessary. Only one hook will have xattr_ctx type.
The normal verifier type enforcement will do its work.

>  		return 0;
> +	}
>  	return -EACCES;
>  }
>  
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 7719f6528445..f14bfcda78db 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -1752,6 +1752,7 @@ struct bpf_prog_aux {
>  	u32 real_func_cnt; /* includes hidden progs, only used for JIT and freeing progs */
>  	u32 func_idx; /* 0 for non-func prog, the index in func array for func prog */
>  	u32 attach_btf_id; /* in-kernel BTF type id to attach to */
> +	u32 attach_limit; /* max concurrent attachments (0 = unlimited) */

no need.

>  	u32 attach_st_ops_member_off;
>  	u32 ctx_arg_info_size;
>  	u32 max_rdonly_access;
> diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h
> index 143775a27a2a..b655c708818e 100644
> --- a/include/linux/bpf_lsm.h
> +++ b/include/linux/bpf_lsm.h
> @@ -19,6 +19,9 @@
>  #include <linux/lsm_hook_defs.h>
>  #undef LSM_HOOK
>  
> +/* max bpf xattrs per inode */
> +#define BPF_LSM_INODE_INIT_XATTRS 4
> +
>  struct bpf_storage_blob {
>  	struct bpf_local_storage __rcu *storage;
>  };
> diff --git a/include/linux/evm.h b/include/linux/evm.h
> index 913f4573b203..0aa151288b36 100644
> --- a/include/linux/evm.h
> +++ b/include/linux/evm.h
> @@ -12,6 +12,8 @@
>  #include <linux/integrity.h>
>  #include <linux/xattr.h>
>  
> +struct xattr_ctx;
> +
>  #ifdef CONFIG_EVM
>  extern int evm_set_key(void *key, size_t keylen);
>  extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
> @@ -21,8 +23,8 @@ extern enum integrity_status evm_verifyxattr(struct dentry *dentry,
>  int evm_fix_hmac(struct dentry *dentry, const char *xattr_name,
>  		 const char *xattr_value, size_t xattr_value_len);
>  int evm_inode_init_security(struct inode *inode, struct inode *dir,
> -			    const struct qstr *qstr, struct xattr *xattrs,
> -			    int *xattr_count);
> +			    const struct qstr *qstr,
> +			    struct xattr_ctx *xattr_ctx);
>  extern bool evm_revalidate_status(const char *xattr_name);
>  extern int evm_protected_xattr_if_enabled(const char *req_xattr_name);
>  extern int evm_read_protected_xattrs(struct dentry *dentry, u8 *buffer,
> @@ -63,8 +65,7 @@ static inline int evm_fix_hmac(struct dentry *dentry, const char *xattr_name,
>  
>  static inline int evm_inode_init_security(struct inode *inode, struct inode *dir,
>  					  const struct qstr *qstr,
> -					  struct xattr *xattrs,
> -					  int *xattr_count)
> +					  struct xattr_ctx *xattr_ctx)
>  {
>  	return 0;
>  }
> diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
> index 65c9609ec207..f62780fbeb9e 100644
> --- a/include/linux/lsm_hook_defs.h
> +++ b/include/linux/lsm_hook_defs.h
> @@ -116,8 +116,8 @@ LSM_HOOK(int, 0, inode_alloc_security, struct inode *inode)
>  LSM_HOOK(void, LSM_RET_VOID, inode_free_security, struct inode *inode)
>  LSM_HOOK(void, LSM_RET_VOID, inode_free_security_rcu, void *inode_security)
>  LSM_HOOK(int, -EOPNOTSUPP, inode_init_security, struct inode *inode,
> -	 struct inode *dir, const struct qstr *qstr, struct xattr *xattrs,
> -	 int *xattr_count)
> +	 struct inode *dir, const struct qstr *qstr,
> +	 struct xattr_ctx *xattr_ctx)
>  LSM_HOOK(int, 0, inode_init_security_anon, struct inode *inode,
>  	 const struct qstr *name, const struct inode *context_inode)
>  LSM_HOOK(int, 0, inode_create, struct inode *dir, struct dentry *dentry,
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index b4f8cad53ddb..710e48caaeba 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -200,20 +200,18 @@ extern struct lsm_static_calls_table static_calls_table __ro_after_init;
>  
>  /**
>   * lsm_get_xattr_slot - Return the next available slot and increment the index
> - * @xattrs: array storing LSM-provided xattrs
> - * @xattr_count: number of already stored xattrs (updated)
> + * @ctx: xattr state shared by inode_init_security hooks
>   *
> - * Retrieve the first available slot in the @xattrs array to fill with an xattr,
> - * and increment @xattr_count.
> + * Retrieve the first available slot in the @ctx->xattrs array to fill with an
> + * xattr, and increment @ctx->xattr_count.
>   *
> - * Return: The slot to fill in @xattrs if non-NULL, NULL otherwise.
> + * Return: The slot to fill in @ctx->xattrs if non-NULL, NULL otherwise.
>   */
> -static inline struct xattr *lsm_get_xattr_slot(struct xattr *xattrs,
> -					       int *xattr_count)
> +static inline struct xattr *lsm_get_xattr_slot(struct xattr_ctx *ctx)
>  {
> -	if (unlikely(!xattrs))
> +	if (unlikely(!ctx || !ctx->xattrs || !ctx->xattr_count))
>  		return NULL;
> -	return &xattrs[(*xattr_count)++];
> +	return &ctx->xattrs[(*ctx->xattr_count)++];
>  }
>  
>  #endif /* ! __LINUX_LSM_HOOKS_H */
> diff --git a/include/linux/security.h b/include/linux/security.h
> index 153e9043058f..1f8e84e7dd7e 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -68,6 +68,11 @@ struct watch;
>  struct watch_notification;
>  struct lsm_ctx;
>  
> +struct xattr_ctx {
> +	struct xattr *xattrs;
> +	int *xattr_count;
> +};
> +
>  /* Default (no) options for the capable function */
>  #define CAP_OPT_NONE 0x0
>  /* If capable should audit the security request */
> diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c
> index 564071a92d7d..86a8e188b900 100644
> --- a/kernel/bpf/bpf_lsm.c
> +++ b/kernel/bpf/bpf_lsm.c
> @@ -113,6 +113,9 @@ void bpf_lsm_find_cgroup_shim(const struct bpf_prog *prog,
>  }
>  #endif
>  
> +BTF_ID_LIST_SINGLE(bpf_lsm_inode_init_security_btf_ids, func,
> +		   bpf_lsm_inode_init_security)
> +
>  int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog,
>  			const struct bpf_prog *prog)
>  {
> @@ -137,6 +140,12 @@ int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog,
>  		return -EINVAL;
>  	}
>  
> +	/* bpf reserves a fixed number of xattr slots for itself.
> +	 * Set the attach limit so the trampoline rejects excess attaches.
> +	 */
> +	if (btf_id == bpf_lsm_inode_init_security_btf_ids[0])
> +		prog->aux->attach_limit = BPF_LSM_INODE_INIT_XATTRS;
> +
>  	return 0;
>  }
>  
> @@ -315,6 +324,7 @@ BTF_ID(func, bpf_lsm_inode_create)
>  BTF_ID(func, bpf_lsm_inode_free_security)
>  BTF_ID(func, bpf_lsm_inode_getattr)
>  BTF_ID(func, bpf_lsm_inode_getxattr)
> +BTF_ID(func, bpf_lsm_inode_init_security)
>  BTF_ID(func, bpf_lsm_inode_mknod)
>  BTF_ID(func, bpf_lsm_inode_need_killpriv)
>  BTF_ID(func, bpf_lsm_inode_post_setxattr)
> diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
> index 1a721fc4bef5..b41b02173e24 100644
> --- a/kernel/bpf/trampoline.c
> +++ b/kernel/bpf/trampoline.c
> @@ -859,6 +859,9 @@ static int bpf_trampoline_add_prog(struct bpf_trampoline *tr,
>  	}
>  	if (cnt >= BPF_MAX_TRAMP_LINKS)
>  		return -E2BIG;
> +	if (node->link->prog->aux->attach_limit &&
> +	    tr->progs_cnt[kind] >= node->link->prog->aux->attach_limit)
> +		return -E2BIG;

No need. The check inside kfunc is enough.

>  	if (!hlist_unhashed(&node->tramp_hlist))
>  		/* prog already linked */
>  		return -EBUSY;
> diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c
> index 40efde233f3a..d7c44c5c0e30 100644
> --- a/security/bpf/hooks.c
> +++ b/security/bpf/hooks.c
> @@ -30,6 +30,7 @@ static int __init bpf_lsm_init(void)
>  
>  struct lsm_blob_sizes bpf_lsm_blob_sizes __ro_after_init = {
>  	.lbs_inode = sizeof(struct bpf_storage_blob),
> +	.lbs_xattr_count = BPF_LSM_INODE_INIT_XATTRS,
>  };
>  
>  DEFINE_LSM(bpf) = {
> diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
> index b59e3f121b8a..e0a05162accc 100644
> --- a/security/integrity/evm/evm_main.c
> +++ b/security/integrity/evm/evm_main.c
> @@ -1062,14 +1062,16 @@ static int evm_inode_copy_up_xattr(struct dentry *src, const char *name)
>   * evm_inode_init_security - initializes security.evm HMAC value
>   */
>  int evm_inode_init_security(struct inode *inode, struct inode *dir,
> -			    const struct qstr *qstr, struct xattr *xattrs,
> -			    int *xattr_count)
> +			    const struct qstr *qstr,
> +			    struct xattr_ctx *xattr_ctx)

the rest looks good.
Pls split the patch. Introduce xattr_ctx first across the LSMs.
Then another patch with a new kfunc.

pw-bot: cr

^ permalink raw reply

* [GIT PULL] TPM DEVICE DRIVER: for-next-tpm-7.2-rc1-fixed
From: Jarkko Sakkinen @ 2026-06-22 15:31 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Peter Huewe, Jason Gunthorpe, David Howells, keyrings,
	linux-integrity, linux-kernel

The following changes since commit 1a3746ccbb0a97bed3c06ccde6b880013b1dddc1:

  Merge tag 'strncpy-removal-v7.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux (2026-06-19 14:56:45 -0700)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git tags/for-next-tpm-7.2-rc1-fixed

for you to fetch changes up to 1a58f6115bfb34eabcc7de8a3a9745b219179781:

  tpm: fix event_size output in tpm1_binary_bios_measurements_show (2026-06-21 04:25:28 +0300)

----------------------------------------------------------------
Hi

Correctly rebased version of [1] now that for-next-tpm was mirrored
today to linux-next by Mark today. Contains only bug fixes.

[1] https://lore.kernel.org/linux-integrity/ajc9JcxcH8eGqxbX@kernel.org/T/#t

BR, Jarkko

----------------------------------------------------------------
Baoli Zhang (1):
      tpm: restore timeout for key creation commands

David Windsor (1):
      tpm: svsm: constify tpm_chip_ops

Gunnar Kudrjavets (1):
      tpm: Initialize name_size_alg for non-NULL name in tpm_buf_append_name()

Jarkko Sakkinen (1):
      tpm: tpm_tis_spi: Use wait_woken() in wait_for_tmp_stat()

Jim Broadus (2):
      tpm: tpm_tis: store entire did_vid
      tpm: tpm_tis: Add settle time for some TPMs

Michael Bommarito (1):
      tpm: tpm2-sessions: wait for async KPP completion in tpm_buf_append_salt

Rafael J. Wysocki (1):
      tpm_crb: Check ACPI_COMPANION() against NULL during probe

Thorsten Blum (1):
      tpm: fix event_size output in tpm1_binary_bios_measurements_show

Yeoreum Yun (1):
      tpm: tpm_crb_ffa: revert defered_probed when tpm_crb_ffa is built-in

 drivers/char/tpm/eventlog/tpm1.c |  4 +--
 drivers/char/tpm/tpm2-cmd.c      |  6 ++--
 drivers/char/tpm/tpm2-sessions.c | 56 +++++++++++++++++++++++++----------
 drivers/char/tpm/tpm_crb.c       |  6 +++-
 drivers/char/tpm/tpm_crb_ffa.c   | 18 ++----------
 drivers/char/tpm/tpm_svsm.c      |  2 +-
 drivers/char/tpm/tpm_tis_core.c  | 63 ++++++++++++++++++++++++++--------------
 drivers/char/tpm/tpm_tis_core.h  |  3 +-
 8 files changed, 98 insertions(+), 60 deletions(-)

^ permalink raw reply

* Re: [PATCH] keys: trusted: dcp: Make dcp_trusted_key_ops const
From: Jarkko Sakkinen @ 2026-06-22 15:24 UTC (permalink / raw)
  To: Berkay Yürekli
  Cc: david, upstream+dcp, James.Bottomley, zohar, linux-integrity,
	keyrings, linux-security-module
In-Reply-To: <CAMyZDTsA-m0R1Ziy74Ck0EPj8UFJhUw-vE0_ACrQ3hiLLaNaKQ@mail.gmail.com>

On Sun, Jun 21, 2026 at 09:05:40PM -0400, Berkay Yürekli wrote:
> Mark the dcp_trusted_key_ops structure as const to improve kernel
> self-protection. This structure contains function pointers that are
> initialized once during module initialization and never modified.
> 
> Making function pointers read-only protects against memory corruption
> attacks where an attacker might overwrite these pointers to redirect
> execution flow, as recommended in Documentation/security/self-protection.rst.
> 
> Signed-off-by: mcss <ps1296@owsa.nl>

full name please

> 
> ---
>  include/keys/trusted_dcp.h          | 2 +-
>  security/keys/trusted-keys/trusted_dcp.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/include/keys/trusted_dcp.h b/include/keys/trusted_dcp.h
> index 9aaa42075b40..8ee24f2d21ff 100644
> --- a/include/keys/trusted_dcp.h
> +++ b/include/keys/trusted_dcp.h
> @@ -6,6 +6,6 @@
>  #ifndef TRUSTED_DCP_H
>  #define TRUSTED_DCP_H
>  
> -extern struct trusted_key_ops dcp_trusted_key_ops;
> +extern const struct trusted_key_ops dcp_trusted_key_ops;
>  
>  #endif
> diff --git a/security/keys/trusted-keys/trusted_dcp.c b/security/keys/
> trusted-keys/trusted_dcp.c
> index 7b6eb655df0c..f638078640f9 100644
> --- a/security/keys/trusted-keys/trusted_dcp.c
> +++ b/security/keys/trusted-keys/trusted_dcp.c
> @@ -347,7 +347,7 @@ static void trusted_dcp_exit(void)
>   unregister_key_type(&key_type_trusted);
>  }
>  
> -struct trusted_key_ops dcp_trusted_key_ops = {
> +const struct trusted_key_ops dcp_trusted_key_ops = {
>   .exit = trusted_dcp_exit,
>   .init = trusted_dcp_init,
>   .seal = trusted_dcp_seal,
> --
> 2.54.0
> 

BR, Jarkko

^ permalink raw reply

* Re: [GIT PULL] TPM DEVICE DRIVER: for-next-tpm-7.2-rc1
From: Jarkko Sakkinen @ 2026-06-21  1:23 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Peter Huewe, Jason Gunthorpe, David Howells, keyrings,
	linux-integrity, linux-kernel
In-Reply-To: <ajboiUkyqgZxHpZS@kernel.org>

Oh crap, sorry.

I'll resend with new tag for-next-tpm-7.2-rc1-2.

Discard.

BR, Jarkko

On Sat, Jun 20, 2026 at 10:22:49PM +0300, Jarkko Sakkinen wrote:
> The following changes since commit 0e0611827f3349d0a2ac121c023a6d3260dcecdb:
> 
>   Merge tag 'pull-fixes' of gitolite.kernel.org:pub/scm/linux/kernel/git/viro/vfs (2026-06-15 15:53:57 +0530)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git tags/for-next-tpm-7.2-rc1
> 
> for you to fetch changes up to 67c53887ebcd425f0003e7068de12eab511f80a9:
> 
>   tpm: fix event_size output in tpm1_binary_bios_measurements_show (2026-06-15 15:19:45 +0300)
> 
> ----------------------------------------------------------------
> Hi,
> 
> Please, pull. This pull request contains only bug fixes.
> 
> BR, Jarkko
> 
> ----------------------------------------------------------------
> Baoli Zhang (1):
>       tpm: restore timeout for key creation commands
> 
> David Laight (1):
>       keys: Replace strcpy(derived_buf, "AUTH_KEY") with strscpy(..., HASH_SIZE)
> 
> David Windsor (1):
>       tpm: svsm: constify tpm_chip_ops
> 
> Eric Biggers (1):
>       KEYS: encrypted: Remove unnecessary selection of CRYPTO_RNG
> 
> Gui-Dong Han (1):
>       KEYS: Use acquire when reading state in keyring search
> 
> Gunnar Kudrjavets (1):
>       tpm: Initialize name_size_alg for non-NULL name in tpm_buf_append_name()
> 
> Jarkko Sakkinen (3):
>       KEYS: fix overflow in keyctl_pkey_params_get_2()
>       KEYS: trusted: Debugging as a feature
>       tpm: tpm_tis_spi: Use wait_woken() in wait_for_tmp_stat()
> 
> Jim Broadus (2):
>       tpm: tpm_tis: store entire did_vid
>       tpm: tpm_tis: Add settle time for some TPMs
> 
> Len Bao (1):
>       keys/trusted_keys: mark 'migratable' as __ro_after_init
> 
> Michael Bommarito (1):
>       tpm: tpm2-sessions: wait for async KPP completion in tpm_buf_append_salt
> 
> Mohammed EL Kadiri (3):
>       keys: prevent slab cache merging for key_jar
>       keys: request_key: replace BUG with return -EINVAL
>       keys: keyctl_pkey: replace BUG with return -EOPNOTSUPP
> 
> Rafael J. Wysocki (1):
>       tpm_crb: Check ACPI_COMPANION() against NULL during probe
> 
> Shaomin Chen (1):
>       keys: Pin request_key_auth payload in instantiate paths
> 
> Thorsten Blum (2):
>       keys: use kmalloc_flex in user_preparse
>       tpm: fix event_size output in tpm1_binary_bios_measurements_show
> 
> Yeoreum Yun (1):
>       tpm: tpm_crb_ffa: revert defered_probed when tpm_crb_ffa is built-in
> 
>  Documentation/admin-guide/kernel-parameters.txt | 16 +++++++
>  drivers/char/tpm/eventlog/tpm1.c                |  4 +-
>  drivers/char/tpm/tpm2-cmd.c                     |  6 +--
>  drivers/char/tpm/tpm2-sessions.c                | 56 ++++++++++++++++------
>  drivers/char/tpm/tpm_crb.c                      |  6 ++-
>  drivers/char/tpm/tpm_crb_ffa.c                  | 18 ++-----
>  drivers/char/tpm/tpm_svsm.c                     |  2 +-
>  drivers/char/tpm/tpm_tis_core.c                 | 63 ++++++++++++++++---------
>  drivers/char/tpm/tpm_tis_core.h                 |  3 +-
>  include/keys/request_key_auth-type.h            |  2 +
>  include/keys/trusted-type.h                     | 21 +++++----
>  security/keys/Kconfig                           |  1 -
>  security/keys/encrypted-keys/encrypted.c        |  4 +-
>  security/keys/internal.h                        |  2 +
>  security/keys/key.c                             |  2 +-
>  security/keys/keyctl.c                          | 24 +++++++---
>  security/keys/keyctl_pkey.c                     | 14 ++++--
>  security/keys/keyring.c                         |  2 +-
>  security/keys/request_key.c                     |  2 +-
>  security/keys/request_key_auth.c                | 33 ++++++++++++-
>  security/keys/trusted-keys/Kconfig              | 23 +++++++++
>  security/keys/trusted-keys/trusted_caam.c       |  7 ++-
>  security/keys/trusted-keys/trusted_core.c       |  8 +++-
>  security/keys/trusted-keys/trusted_tpm1.c       | 44 +++++++++--------
>  security/keys/user_defined.c                    |  2 +-
>  25 files changed, 256 insertions(+), 109 deletions(-)


^ permalink raw reply

* [GIT PULL] TPM DEVICE DRIVER: for-next-tpm-7.2-rc1
From: Jarkko Sakkinen @ 2026-06-20 19:22 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Peter Huewe, Jason Gunthorpe, David Howells, keyrings,
	linux-integrity, linux-kernel

The following changes since commit 0e0611827f3349d0a2ac121c023a6d3260dcecdb:

  Merge tag 'pull-fixes' of gitolite.kernel.org:pub/scm/linux/kernel/git/viro/vfs (2026-06-15 15:53:57 +0530)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git tags/for-next-tpm-7.2-rc1

for you to fetch changes up to 67c53887ebcd425f0003e7068de12eab511f80a9:

  tpm: fix event_size output in tpm1_binary_bios_measurements_show (2026-06-15 15:19:45 +0300)

----------------------------------------------------------------
Hi,

Please, pull. This pull request contains only bug fixes.

BR, Jarkko

----------------------------------------------------------------
Baoli Zhang (1):
      tpm: restore timeout for key creation commands

David Laight (1):
      keys: Replace strcpy(derived_buf, "AUTH_KEY") with strscpy(..., HASH_SIZE)

David Windsor (1):
      tpm: svsm: constify tpm_chip_ops

Eric Biggers (1):
      KEYS: encrypted: Remove unnecessary selection of CRYPTO_RNG

Gui-Dong Han (1):
      KEYS: Use acquire when reading state in keyring search

Gunnar Kudrjavets (1):
      tpm: Initialize name_size_alg for non-NULL name in tpm_buf_append_name()

Jarkko Sakkinen (3):
      KEYS: fix overflow in keyctl_pkey_params_get_2()
      KEYS: trusted: Debugging as a feature
      tpm: tpm_tis_spi: Use wait_woken() in wait_for_tmp_stat()

Jim Broadus (2):
      tpm: tpm_tis: store entire did_vid
      tpm: tpm_tis: Add settle time for some TPMs

Len Bao (1):
      keys/trusted_keys: mark 'migratable' as __ro_after_init

Michael Bommarito (1):
      tpm: tpm2-sessions: wait for async KPP completion in tpm_buf_append_salt

Mohammed EL Kadiri (3):
      keys: prevent slab cache merging for key_jar
      keys: request_key: replace BUG with return -EINVAL
      keys: keyctl_pkey: replace BUG with return -EOPNOTSUPP

Rafael J. Wysocki (1):
      tpm_crb: Check ACPI_COMPANION() against NULL during probe

Shaomin Chen (1):
      keys: Pin request_key_auth payload in instantiate paths

Thorsten Blum (2):
      keys: use kmalloc_flex in user_preparse
      tpm: fix event_size output in tpm1_binary_bios_measurements_show

Yeoreum Yun (1):
      tpm: tpm_crb_ffa: revert defered_probed when tpm_crb_ffa is built-in

 Documentation/admin-guide/kernel-parameters.txt | 16 +++++++
 drivers/char/tpm/eventlog/tpm1.c                |  4 +-
 drivers/char/tpm/tpm2-cmd.c                     |  6 +--
 drivers/char/tpm/tpm2-sessions.c                | 56 ++++++++++++++++------
 drivers/char/tpm/tpm_crb.c                      |  6 ++-
 drivers/char/tpm/tpm_crb_ffa.c                  | 18 ++-----
 drivers/char/tpm/tpm_svsm.c                     |  2 +-
 drivers/char/tpm/tpm_tis_core.c                 | 63 ++++++++++++++++---------
 drivers/char/tpm/tpm_tis_core.h                 |  3 +-
 include/keys/request_key_auth-type.h            |  2 +
 include/keys/trusted-type.h                     | 21 +++++----
 security/keys/Kconfig                           |  1 -
 security/keys/encrypted-keys/encrypted.c        |  4 +-
 security/keys/internal.h                        |  2 +
 security/keys/key.c                             |  2 +-
 security/keys/keyctl.c                          | 24 +++++++---
 security/keys/keyctl_pkey.c                     | 14 ++++--
 security/keys/keyring.c                         |  2 +-
 security/keys/request_key.c                     |  2 +-
 security/keys/request_key_auth.c                | 33 ++++++++++++-
 security/keys/trusted-keys/Kconfig              | 23 +++++++++
 security/keys/trusted-keys/trusted_caam.c       |  7 ++-
 security/keys/trusted-keys/trusted_core.c       |  8 +++-
 security/keys/trusted-keys/trusted_tpm1.c       | 44 +++++++++--------
 security/keys/user_defined.c                    |  2 +-
 25 files changed, 256 insertions(+), 109 deletions(-)

^ permalink raw reply

* Re: [GIT PULL] TPM DEVICE DRIVER: for-next-keys-7.2-rc1
From: pr-tracker-bot @ 2026-06-19 19:24 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: Linus Torvalds, Peter Huewe, Jason Gunthorpe, David Howells,
	keyrings, linux-integrity, linux-kernel
In-Reply-To: <ajSR22PC_X6HWjo2@kernel.org>

The pull request you sent on Fri, 19 Jun 2026 03:48:27 +0300:

> git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git tags/for-next-keys-7.2-rc1

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/e2c0595b56e9526e67ddd228fc35fa9ff20724ec

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

^ permalink raw reply

* Re: [GIT PULL] integrity: subsystem fixes for v7.2
From: pr-tracker-bot @ 2026-06-19 19:24 UTC (permalink / raw)
  To: Mimi Zohar; +Cc: Linus Torvalds, linux-integrity, linux-kernel, Roberto Sassu
In-Reply-To: <2a5a07ef24454c295c3a63ae8cedcd6c47578101.camel@linux.ibm.com>

The pull request you sent on Thu, 18 Jun 2026 10:06:01 -0400:

> https://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity.git/ tags/integrity-v7.2

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/0798268aa4c26ece25020b3ddeeef9a5941209c0

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

^ permalink raw reply

* [PATCH] ima: correctly recover number of violations after kexec
From: Enrico Bravi @ 2026-06-19 19:14 UTC (permalink / raw)
  To: linux-integrity, zohar, dmitry.kasatkin, roberto.sassu
  Cc: eric.snowberg, Enrico Bravi

When recovering the measurement list after kexec(), the number of
violations is not recovered as well, causing a mismatch between the
number reported by the <securityfs>/ima/violations user interface and
the actual value. In addition, currently it is assumed that when
recovering an entry, this is a violation if the template data hash
read from the kexec buffer is an all-zero hash, which can actually be a
valid hash.

Verify that an all-zero hash corresponds to a violation and consequently
correctly recover the number of violations.

Reported-by: Roberto Sassu <roberto.sassu@huawei.com>
Closes: https://github.com/linux-integrity/linux/issues/13
Signed-off-by: Enrico Bravi <enrico.bravi@polito.it>

---
 security/integrity/ima/ima_template.c | 28 ++++++++++++++++++++-------
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c
index 7034573fb41e..147f228ed246 100644
--- a/security/integrity/ima/ima_template.c
+++ b/security/integrity/ima/ima_template.c
@@ -430,6 +430,7 @@ int ima_restore_measurement_list(loff_t size, void *buf)
 	DECLARE_BITMAP(hdr_mask, HDR__LAST);
 	unsigned long count = 0;
 	int ret = 0;
+	int i;
 
 	if (!buf || size < sizeof(*khdr))
 		return 0;
@@ -515,15 +516,28 @@ int ima_restore_measurement_list(loff_t size, void *buf)
 		if (ret < 0)
 			break;
 
-		if (memcmp(hdr[HDR_DIGEST].data, zero, sizeof(zero))) {
-			ret = ima_calc_field_array_hash(
-						&entry->template_data[0],
+		ret = ima_calc_field_array_hash(&entry->template_data[0],
 						entry);
-			if (ret < 0) {
-				pr_err("cannot calculate template digest\n");
-				ret = -EINVAL;
-				break;
+		if (ret < 0) {
+			pr_err("cannot calculate template digest\n");
+			ret = -EINVAL;
+			break;
+		}
+
+		if (!memcmp(hdr[HDR_DIGEST].data, zero, sizeof(zero)) &&
+		    memcmp(entry->digests[ima_sha1_idx].digest, zero, sizeof(zero))) {
+			for (i = 0; i < NR_BANKS(ima_tpm_chip) + ima_extra_slots; i++) {
+				/* Unmapped TPM algorithms */
+				if (!ima_algo_array[i].tfm) {
+					memset(entry->digests[i].digest, 0,
+					       TPM_DIGEST_SIZE);
+					continue;
+				}
+
+				memset(entry->digests[i].digest, 0,
+				       ima_algo_array[i].digest_size);
 			}
+			atomic_long_inc(&ima_htable.violations);
 		}
 
 		entry->pcr = !ima_canonical_fmt ? *(u32 *)(hdr[HDR_PCR].data) :

base-commit: 8cd9520d35a6c38db6567e97dd93b1f11f185dc6
-- 
2.52.0


^ permalink raw reply related

* Re: [PATCH bpf-next v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: Christian Brauner @ 2026-06-19 10:25 UTC (permalink / raw)
  To: David Windsor
  Cc: viro, jack, ast, daniel, john.fastabend, andrii, eddyz87, memxor,
	martin.lau, song, yonghong.song, jolsa, emil, kpsingh,
	mattbobrowski, paul, jmorris, serge, zohar, roberto.sassu,
	dmitry.kasatkin, eric.snowberg, stephen.smalley.work, omosnace,
	casey, shuah, linux-kernel, linux-fsdevel, bpf,
	linux-security-module, linux-integrity, selinux, linux-kselftest
In-Reply-To: <20260618203411.73917-2-dwindsor@gmail.com>

On Thu, Jun 18, 2026 at 04:34:10PM -0400, David Windsor wrote:
> Add bpf_init_inode_xattr() kfunc for BPF LSM programs to atomically set
> xattrs via the inode_init_security hook using lsm_get_xattr_slot().
> 
> The inode_init_security hook previously took the xattr array and count
> as two separate output parameters (struct xattr *xattrs, int
> *xattr_count), which BPF programs cannot write to. Pass the xattr state
> as a single context object (struct xattr_ctx) instead, and have
> bpf_init_inode_xattr() take that context directly. Update the existing
> in-tree callers of inode_init_security to take and forward the new
> xattr_ctx.
> 
> A previous attempt [1] required a kmalloc string output protocol for
> the xattr name. Since commit 6bcdfd2cac55 ("security: Allow all LSMs to
> provide xattrs for inode_init_security hook") [2], the xattr name is no
> longer allocated; it is a static constant.
> 
> Because we rely on the hook-specific ctx layout, the kfunc is
> restricted to lsm/inode_init_security. Restrict the xattr names that
> may be set via this kfunc to the bpf.* namespace.
> 
> Link: https://kernsec.org/pipermail/linux-security-module-archive/2022-October/034878.html [1]
> Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6bcdfd2cac55 [2]
> Suggested-by: Song Liu <song@kernel.org>
> Signed-off-by: David Windsor <dwindsor@gmail.com>
> ---
>  fs/bpf_fs_kfuncs.c                | 106 +++++++++++++++++++++++++++++-

Please split this into the VFS changes and lsm changes required for
this. The api change to the lsm layer can be done independently of any
of the actual VFS level wiring. Will also make it a lot nicer to
review...

^ permalink raw reply

* [GIT PULL] KEYS: for-next-keys-7.2-rc1-2
From: Jarkko Sakkinen @ 2026-06-19  0:51 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: David Howells, Herbert Xu, David S. Miller, keyrings,
	linux-integrity

The following changes since commit 0e0611827f3349d0a2ac121c023a6d3260dcecdb:

  Merge tag 'pull-fixes' of gitolite.kernel.org:pub/scm/linux/kernel/git/viro/vfs (2026-06-15 15:53:57 +0530)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git tags/for-next-keys-7.2-rc1-2

for you to fetch changes up to 1b9524250996b1f2f49833a1b2ae21c34e486f85:

  keys: keyctl_pkey: replace BUG with return -EOPNOTSUPP (2026-06-15 15:19:13 +0300)

----------------------------------------------------------------
Hi,

Please, pull. This pull request contains only bug fixes.

BR, Jarkko

----------------------------------------------------------------
David Laight (1):
      keys: Replace strcpy(derived_buf, "AUTH_KEY") with strscpy(..., HASH_SIZE)

Eric Biggers (1):
      KEYS: encrypted: Remove unnecessary selection of CRYPTO_RNG

Gui-Dong Han (1):
      KEYS: Use acquire when reading state in keyring search

Jarkko Sakkinen (2):
      KEYS: fix overflow in keyctl_pkey_params_get_2()
      KEYS: trusted: Debugging as a feature

Len Bao (1):
      keys/trusted_keys: mark 'migratable' as __ro_after_init

Mohammed EL Kadiri (3):
      keys: prevent slab cache merging for key_jar
      keys: request_key: replace BUG with return -EINVAL
      keys: keyctl_pkey: replace BUG with return -EOPNOTSUPP

Shaomin Chen (1):
      keys: Pin request_key_auth payload in instantiate paths

Thorsten Blum (1):
      keys: use kmalloc_flex in user_preparse

 Documentation/admin-guide/kernel-parameters.txt | 16 +++++++++
 include/keys/request_key_auth-type.h            |  2 ++
 include/keys/trusted-type.h                     | 21 +++++++-----
 security/keys/Kconfig                           |  1 -
 security/keys/encrypted-keys/encrypted.c        |  4 +--
 security/keys/internal.h                        |  2 ++
 security/keys/key.c                             |  2 +-
 security/keys/keyctl.c                          | 24 ++++++++++----
 security/keys/keyctl_pkey.c                     | 14 ++++++--
 security/keys/keyring.c                         |  2 +-
 security/keys/request_key.c                     |  2 +-
 security/keys/request_key_auth.c                | 33 +++++++++++++++++--
 security/keys/trusted-keys/Kconfig              | 23 +++++++++++++
 security/keys/trusted-keys/trusted_caam.c       |  7 ++--
 security/keys/trusted-keys/trusted_core.c       |  8 ++++-
 security/keys/trusted-keys/trusted_tpm1.c       | 44 ++++++++++++++-----------
 security/keys/user_defined.c                    |  2 +-
 17 files changed, 158 insertions(+), 49 deletions(-)

^ permalink raw reply

* Re: [GIT PULL] TPM DEVICE DRIVER: for-next-keys-7.2-rc1
From: Jarkko Sakkinen @ 2026-06-19  0:49 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Peter Huewe, Jason Gunthorpe, David Howells, keyrings,
	linux-integrity, linux-kernel

OOPS please ignore I'll resend this!

Wrong template apologies.

BR, Jarkko

On Fri, Jun 19, 2026 at 12:47:08AM +0000, jarkko@kernel.org wrote:
> The following changes since commit 0e0611827f3349d0a2ac121c023a6d3260dcecdb:
> 
>   Merge tag 'pull-fixes' of gitolite.kernel.org:pub/scm/linux/kernel/git/viro/vfs (2026-06-15 15:53:57 +0530)
> 
> are available in the Git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git tags/for-next-keys-7.2-rc1
> 
> for you to fetch changes up to 1b9524250996b1f2f49833a1b2ae21c34e486f85:
> 
>   keys: keyctl_pkey: replace BUG with return -EOPNOTSUPP (2026-06-15 15:19:13 +0300)
> 
> ----------------------------------------------------------------
> Hi
> 
> Please, pull. This pull request contains only fixes.
> 
> BR, Jarkko
> 
> ----------------------------------------------------------------
> David Laight (1):
>       keys: Replace strcpy(derived_buf, "AUTH_KEY") with strscpy(..., HASH_SIZE)
> 
> Eric Biggers (1):
>       KEYS: encrypted: Remove unnecessary selection of CRYPTO_RNG
> 
> Gui-Dong Han (1):
>       KEYS: Use acquire when reading state in keyring search
> 
> Jarkko Sakkinen (2):
>       KEYS: fix overflow in keyctl_pkey_params_get_2()
>       KEYS: trusted: Debugging as a feature
> 
> Len Bao (1):
>       keys/trusted_keys: mark 'migratable' as __ro_after_init
> 
> Mohammed EL Kadiri (3):
>       keys: prevent slab cache merging for key_jar
>       keys: request_key: replace BUG with return -EINVAL
>       keys: keyctl_pkey: replace BUG with return -EOPNOTSUPP
> 
> Shaomin Chen (1):
>       keys: Pin request_key_auth payload in instantiate paths
> 
> Thorsten Blum (1):
>       keys: use kmalloc_flex in user_preparse
> 
>  Documentation/admin-guide/kernel-parameters.txt | 16 +++++++++
>  include/keys/request_key_auth-type.h            |  2 ++
>  include/keys/trusted-type.h                     | 21 +++++++-----
>  security/keys/Kconfig                           |  1 -
>  security/keys/encrypted-keys/encrypted.c        |  4 +--
>  security/keys/internal.h                        |  2 ++
>  security/keys/key.c                             |  2 +-
>  security/keys/keyctl.c                          | 24 ++++++++++----
>  security/keys/keyctl_pkey.c                     | 14 ++++++--
>  security/keys/keyring.c                         |  2 +-
>  security/keys/request_key.c                     |  2 +-
>  security/keys/request_key_auth.c                | 33 +++++++++++++++++--
>  security/keys/trusted-keys/Kconfig              | 23 +++++++++++++
>  security/keys/trusted-keys/trusted_caam.c       |  7 ++--
>  security/keys/trusted-keys/trusted_core.c       |  8 ++++-
>  security/keys/trusted-keys/trusted_tpm1.c       | 44 ++++++++++++++-----------
>  security/keys/user_defined.c                    |  2 +-
>  17 files changed, 158 insertions(+), 49 deletions(-)

^ permalink raw reply

* [GIT PULL] TPM DEVICE DRIVER: for-next-keys-7.2-rc1
From: Jarkko Sakkinen @ 2026-06-19  0:48 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Peter Huewe, Jason Gunthorpe, David Howells, keyrings,
	linux-integrity, linux-kernel

The following changes since commit 0e0611827f3349d0a2ac121c023a6d3260dcecdb:

  Merge tag 'pull-fixes' of gitolite.kernel.org:pub/scm/linux/kernel/git/viro/vfs (2026-06-15 15:53:57 +0530)

are available in the Git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git tags/for-next-keys-7.2-rc1

for you to fetch changes up to 1b9524250996b1f2f49833a1b2ae21c34e486f85:

  keys: keyctl_pkey: replace BUG with return -EOPNOTSUPP (2026-06-15 15:19:13 +0300)

----------------------------------------------------------------
Hi

Please, pull. This pull request contains only fixes.

BR, Jarkko

----------------------------------------------------------------
David Laight (1):
      keys: Replace strcpy(derived_buf, "AUTH_KEY") with strscpy(..., HASH_SIZE)

Eric Biggers (1):
      KEYS: encrypted: Remove unnecessary selection of CRYPTO_RNG

Gui-Dong Han (1):
      KEYS: Use acquire when reading state in keyring search

Jarkko Sakkinen (2):
      KEYS: fix overflow in keyctl_pkey_params_get_2()
      KEYS: trusted: Debugging as a feature

Len Bao (1):
      keys/trusted_keys: mark 'migratable' as __ro_after_init

Mohammed EL Kadiri (3):
      keys: prevent slab cache merging for key_jar
      keys: request_key: replace BUG with return -EINVAL
      keys: keyctl_pkey: replace BUG with return -EOPNOTSUPP

Shaomin Chen (1):
      keys: Pin request_key_auth payload in instantiate paths

Thorsten Blum (1):
      keys: use kmalloc_flex in user_preparse

 Documentation/admin-guide/kernel-parameters.txt | 16 +++++++++
 include/keys/request_key_auth-type.h            |  2 ++
 include/keys/trusted-type.h                     | 21 +++++++-----
 security/keys/Kconfig                           |  1 -
 security/keys/encrypted-keys/encrypted.c        |  4 +--
 security/keys/internal.h                        |  2 ++
 security/keys/key.c                             |  2 +-
 security/keys/keyctl.c                          | 24 ++++++++++----
 security/keys/keyctl_pkey.c                     | 14 ++++++--
 security/keys/keyring.c                         |  2 +-
 security/keys/request_key.c                     |  2 +-
 security/keys/request_key_auth.c                | 33 +++++++++++++++++--
 security/keys/trusted-keys/Kconfig              | 23 +++++++++++++
 security/keys/trusted-keys/trusted_caam.c       |  7 ++--
 security/keys/trusted-keys/trusted_core.c       |  8 ++++-
 security/keys/trusted-keys/trusted_tpm1.c       | 44 ++++++++++++++-----------
 security/keys/user_defined.c                    |  2 +-
 17 files changed, 158 insertions(+), 49 deletions(-)

^ permalink raw reply

* Re: inherit null-key across hibernate (was: Re: regression: kernel log "flooded" with tpm tpm0: A TPM error (2306) occurred attempting to create NULL primary)
From: Jarkko Sakkinen @ 2026-06-19  0:38 UTC (permalink / raw)
  To: Daniel Golle; +Cc: James Bottomley, Christoph Anton Mitterer, linux-integrity
In-Reply-To: <ajDIDcW_EzgLB0qX@makrotopia.org>

On Tue, Jun 16, 2026 at 04:50:37AM +0100, Daniel Golle wrote:
> Hi Jarkko,
> Hi James,
> 
> first of all, sorry for hijacking a thread from 2 years ago.
> 
> On Thu, Nov 14, 2024 at 12:34:30AM +0200, Jarkko Sakkinen wrote:
> > On Wed Nov 13, 2024 at 8:12 PM EET, James Bottomley wrote:
> > > > I think we might have to expect the NULL name to change on actual
> > > > hibernation because unlike suspend to ram it does power off the TPM.
> > >
> > > I checked the code: we're coming in on the correct path to renew the
> > > null seed after hibernation, so it should all work.  The problem seems
> > > to be that your TPM itself is doing something invalid because the name
> > > we calculate for the primary key doesn't match what your TPM says it
> > > should be.  Absent some form of attack or bus integrity problem, that
> > > shouldn't ever happen, so I'm even more curious to know why it worked
> > > in 6.11.5 and before and whether current upstream works.
> > >
> > > I haven't found it yet, but I think the every 10s signature is because
> > > the hibernation path is trying to restart the TPM device and won't take
> > > no for an answer.
> > 
> > My fix returned the behavior how it was before my earlier fix in this
> > corner case (i.e. disable TPM). The issue has gone unnoticed before
> > since it has emitted only a single klog entry.
> > 
> > On suspend this has not happened to me so obvious deduction is that
> > hibernate resets the null seed.
> > 
> > Hibernate needs an addition a fix to disable bus encryption from kernel
> > command-line completely, i.e. tpm.disable_integrity following the
> > convention from my earlier fix [1].
> 
> I'd like to offer a way it might be resolvable with the null key after
> all, without provisioning a persistent NV key -- by changing the
> question from "re-derive the null primary and compare" to "inherit the
> trust the resume has already established".
> 
> Resume-from-hibernation is a TPM Restart (Shutdown(STATE) ->
> Startup(CLEAR)), i.e. a firmware cold-init of the (f)TPM, after which
> the boot/initramfs kernel establishes a fresh, genuine null primary.
> In the common configuration (FDE with the resume/swap device inside
> a TPM-sealed LUKS2 container) that same TPM has, moments earlier and
> *before* the hibernation image is restored, cryptographically attested
> itself by unsealing the resume device. A substituted or interposed TPM
> cannot produce that unseal.
> 
> So rather than letting the resumed kernel re-derive the null name,
> find a mismatch and disable the chip, the boot kernel's
> freshly-established and unseal-validated null primary could be
> inherited by the resumed image. The existing null-seed TOFU model is
> preserved; nothing new is provisioned.
> 
> The gate is the unseal, and the adversary case shows why it is the
> right gate:
> 
>   Malice swaps (or interposes on) the TPM while the machine is
>   hibernated, then leaves. Alice powers on. The initramfs attempts the
>   TPM unseal of the resume device; with a foreign TPM it fails, so
>   systemd-cryptsetup falls back to the passphrase, which Alice --
>   seeing a prompt -- types. The disk opens and the system resumes.
> 
> If trust were re-established here, Alice would have personally vouched
> for Malice's TPM. But the unseal *failed*, so under this scheme
> nothing is inherited and the chip stays fail-closed exactly as today.
> The passphrase proves a human is present; it never proves the TPM is
> the genuine one.
> Hence: unseal succeeded -> inherit the validated null primary;
> passphrase fallback -> trust is lost, stay disabled.
> 
> This keeps the property the null-seed design wants -- an in-session
> reset is not on the hibernate-restore path and is still caught --
> while removing the false positive only where the platform has already
> re-attested the TPM.
> 
> The hard parts, and where I'd value direction:
> 
>  - systemd-cryptsetup would need to signal "the resume device was
>    unsealed by the TPM this boot" (vs. the passphrase fallback).
>    This is per-resume runtime state; a static command-line parameter
>    (and obviously build-time config as well) cannot represent it.
> 
>  - the validated null primary has to cross the boot -> resumed memory
>    discontinuity (the initramfs kernel's state is overwritten by the
>    restored image). Boot and image kernel are the same binary, so
>    patching chip->null_key_name in the restored image is mechanically
>    possible; a small reserved/nosave hand-off area may be cleaner.
>    I don't know the hibernate path well enough to say which is right.
> 
> It is admittedly cross-subsystem (tpm + pm/hibernate +
> systemd/cryptsetup), which is presumably why it hasn't been done.
> Compared with the persistent NV-key route
> (tpm.integrity_key=<handle>): that avoids the carry-across but needs
> the key provisioned and managed, and a persistent key's name no longer
> changes on a genuine reset, so the implicit reset detection has to be
> reconstructed. The null-key-inherit approach keeps the existing model
> and defers "is this the same TPM?" to the unseal that has already
> happened.
> 
> Does this seem viable, or is there a reason the unseal-as-attestation
> gate does not hold that I'm missing?
> 
> (For motivation: on a firmware TPM -- Intel PTT here -- there is no
> external bus to interpose, so the protection has no benefit on this
> class of hardware at all, yet the legitimate hibernation power-cycle
> still trips the disable. For fTPMs specifically, not enabling the
> feature is arguably the better answer; but for discrete TPMs that
> hibernate, a real solution seems a good idea if doable.)

I think this has at least changed since 2024: bootc container type
of deployment is where you can realistically configure hibernate,
and use it in a real application.

> 
> 
> Cheers
> 
> 
> Daniel

BR, Jarkko

^ permalink raw reply


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