* Re: [RFC PATCH 1/4] security: ima: move ima_init into late_initcall_sync
From: Yeoreum Yun @ 2026-04-21 12:50 UTC (permalink / raw)
To: Mimi Zohar
Cc: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm, paul, jmorris, serge, roberto.sassu,
dmitry.kasatkin, eric.snowberg, peterhuewe, jarkko, jgg,
sudeep.holla, maz, oupton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will
In-Reply-To: <a6a0e15286c983d720de227c6827adbe976c5b9b.camel@linux.ibm.com>
Hi Mimi,
> On Fri, 2026-04-17 at 18:57 +0100, Yeoreum Yun wrote:
> > To generate the boot_aggregate log in the IMA subsystem with TPM PCR values,
> > the TPM driver must be built as built-in and
> > must be probed before the IMA subsystem is initialized.
> >
> > However, when the TPM device operates over the FF-A protocol using
> > the CRB interface, probing fails and returns -EPROBE_DEFER if
> > the tpm_crb_ffa device — an FF-A device that provides the communication
> > interface to the tpm_crb driver — has not yet been probed.
> >
> > To ensure the TPM device operating over the FF-A protocol with
> > the CRB interface is probed before IMA initialization,
> > the following conditions must be met:
> >
> > 1. The corresponding ffa_device must be registered,
> > which is done via ffa_init().
> >
> > 2. The tpm_crb_driver must successfully probe this device via
> > tpm_crb_ffa_init().
> >
> > 3. The tpm_crb driver using CRB over FF-A can then
> > be probed successfully. (See crb_acpi_add() and
> > tpm_crb_ffa_init() for reference.)
> >
> > Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
> > all registered with device_initcall, which means crb_acpi_driver_init() may
> > be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
> >
> > When this occurs, probing the TPM device is deferred.
> > However, the deferred probe can happen after the IMA subsystem
> > has already been initialized, since IMA initialization is performed
> > during late_initcall, and deferred_probe_initcall() is performed
> > at the same level.
> >
> > To resolve this, move ima_init() into late_inicall_sync level
> > so that let IMA not miss TPM PCR value when generating boot_aggregate
> > log though TPM device presents in the system.
> >
> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
>
> IMA should be initialized as early as possible. I'm really hesitant to defer
> ima_init() to late_initcall_sync() for systems that the TPM is currently
> initialized in time. For these systems, continue initializing IMA at
> late_initcall(). As a compromise for those systems that the TPM isn't properly
> initialized in time, define and instantiate the late_initcall_sync().
>
> ima_init() would need to differentiate between the late_initcall and
> late_initcall_sync. On late_initcall(), instead of saying "No TPM chip found,
> activating TPM-bypass!", it should say "No TPM chip found, deferring to
> late_initcall_sync" or something similar.
But can we really move those initialisations to be called again?
I am referring to functions such as ima_init_crypto(),
ima_add_boot_aggregate(), and ima_measure_critical_data() in ima_init()—
first without TPM, and then a second time once TPM becomes available.
I don’t think that approach would work.
In other words, unless tpm_default_chip() can differentiate between a TPM
device that is deferred and one that does not exist, we cannot distinguish
between the “defer” case and “-EEXIST”.
It might be possible if the TPM core tracked the state when a driver returns
-EPROBE_DEFER, but I am not sure that is the right approach.
For deferred probe cases, the “device initialised in time” check should
likely be done at late_initcall_sync, rather than late_initcall.
This implies that any such check performed before late_initcall_sync
does not reflect a valid state, as it cannot distinguish between “not
present” and “deferred”.
Therefore, I think the TPM check in IMA should be performed at
late_initcall_sync.
Am I missing something?
Thanks.
>
> > ---
> > include/linux/lsm_hooks.h | 2 ++
> > security/integrity/ima/ima_main.c | 2 +-
> > security/lsm_init.c | 13 +++++++++++--
> > 3 files changed, 14 insertions(+), 3 deletions(-)
> >
> > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> > index d48bf0ad26f4..88fe105b7f00 100644
> > --- a/include/linux/lsm_hooks.h
> > +++ b/include/linux/lsm_hooks.h
> > @@ -166,6 +166,7 @@ enum lsm_order {
> > * @initcall_fs: LSM callback for fs_initcall setup, optional
> > * @initcall_device: LSM callback for device_initcall() setup, optional
> > * @initcall_late: LSM callback for late_initcall() setup, optional
> > + * @initcall_late_sync: LSM callback for late_initcall_sync() setup, optional
> > */
> > struct lsm_info {
> > const struct lsm_id *id;
> > @@ -181,6 +182,7 @@ struct lsm_info {
> > int (*initcall_fs)(void);
> > int (*initcall_device)(void);
> > int (*initcall_late)(void);
> > + int (*initcall_late_sync)(void);
> > };
> >
> > #define DEFINE_LSM(lsm) \
> > diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> > index 1d6229b156fb..ace280fa3212 100644
> > --- a/security/integrity/ima/ima_main.c
> > +++ b/security/integrity/ima/ima_main.c
> > @@ -1320,5 +1320,5 @@ DEFINE_LSM(ima) = {
> > .order = LSM_ORDER_LAST,
> > .blobs = &ima_blob_sizes,
> > /* Start IMA after the TPM is available */
> > - .initcall_late = init_ima,
> > + .initcall_late_sync = init_ima,
> > };
> > diff --git a/security/lsm_init.c b/security/lsm_init.c
> > index 573e2a7250c4..4e5c59beb82a 100644
> > --- a/security/lsm_init.c
> > +++ b/security/lsm_init.c
> > @@ -547,13 +547,22 @@ device_initcall(security_initcall_device);
> > * security_initcall_late - Run the LSM late initcalls
> > */
> > static int __init security_initcall_late(void)
> > +{
> > + return lsm_initcall(late);
> > +}
> > +late_initcall(security_initcall_late);
> > +
> > +/**
> > + * security_initcall_late_sync - Run the LSM late initcalls sync
> > + */
> > +static int __init security_initcall_late_sync(void)
> > {
> > int rc;
> >
> > - rc = lsm_initcall(late);
> > + rc = lsm_initcall(late_sync);
> > lsm_pr_dbg("all enabled LSMs fully activated\n");
> > call_blocking_lsm_notifier(LSM_STARTED_ALL, NULL);
> >
> > return rc;
> > }
> > -late_initcall(security_initcall_late);
> > +late_initcall_sync(security_initcall_late_sync);
> > --
> > LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
> >
--
Sincerely,
Yeoreum Yun
^ permalink raw reply
* Re: [RFC PATCH 1/4] security: ima: move ima_init into late_initcall_sync
From: Mimi Zohar @ 2026-04-21 13:26 UTC (permalink / raw)
To: Yeoreum Yun
Cc: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm, paul, jmorris, serge, roberto.sassu,
dmitry.kasatkin, eric.snowberg, peterhuewe, jarkko, jgg,
sudeep.holla, maz, oupton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will
In-Reply-To: <aedyh61iTnQRyzMv@e129823.arm.com>
On Tue, 2026-04-21 at 13:50 +0100, Yeoreum Yun wrote:
> Hi Mimi,
>
> > On Fri, 2026-04-17 at 18:57 +0100, Yeoreum Yun wrote:
> > > To generate the boot_aggregate log in the IMA subsystem with TPM PCR values,
> > > the TPM driver must be built as built-in and
> > > must be probed before the IMA subsystem is initialized.
> > >
> > > However, when the TPM device operates over the FF-A protocol using
> > > the CRB interface, probing fails and returns -EPROBE_DEFER if
> > > the tpm_crb_ffa device — an FF-A device that provides the communication
> > > interface to the tpm_crb driver — has not yet been probed.
> > >
> > > To ensure the TPM device operating over the FF-A protocol with
> > > the CRB interface is probed before IMA initialization,
> > > the following conditions must be met:
> > >
> > > 1. The corresponding ffa_device must be registered,
> > > which is done via ffa_init().
> > >
> > > 2. The tpm_crb_driver must successfully probe this device via
> > > tpm_crb_ffa_init().
> > >
> > > 3. The tpm_crb driver using CRB over FF-A can then
> > > be probed successfully. (See crb_acpi_add() and
> > > tpm_crb_ffa_init() for reference.)
> > >
> > > Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
> > > all registered with device_initcall, which means crb_acpi_driver_init() may
> > > be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
> > >
> > > When this occurs, probing the TPM device is deferred.
> > > However, the deferred probe can happen after the IMA subsystem
> > > has already been initialized, since IMA initialization is performed
> > > during late_initcall, and deferred_probe_initcall() is performed
> > > at the same level.
> > >
> > > To resolve this, move ima_init() into late_inicall_sync level
> > > so that let IMA not miss TPM PCR value when generating boot_aggregate
> > > log though TPM device presents in the system.
> > >
> > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> >
> > IMA should be initialized as early as possible. I'm really hesitant to defer
> > ima_init() to late_initcall_sync() for systems that the TPM is currently
> > initialized in time. For these systems, continue initializing IMA at
> > late_initcall(). As a compromise for those systems that the TPM isn't properly
> > initialized in time, define and instantiate the late_initcall_sync().
> >
> > ima_init() would need to differentiate between the late_initcall and
> > late_initcall_sync. On late_initcall(), instead of saying "No TPM chip found,
> > activating TPM-bypass!", it should say "No TPM chip found, deferring to
> > late_initcall_sync" or something similar.
>
> But can we really move those initialisations to be called again?
>
> I am referring to functions such as ima_init_crypto(),
> ima_add_boot_aggregate(), and ima_measure_critical_data() in ima_init()—
> first without TPM, and then a second time once TPM becomes available.
> I don’t think that approach would work.
>
> In other words, unless tpm_default_chip() can differentiate between a TPM
> device that is deferred and one that does not exist, we cannot distinguish
> between the “defer” case and “-EEXIST”.
>
> It might be possible if the TPM core tracked the state when a driver returns
> -EPROBE_DEFER, but I am not sure that is the right approach.
> For deferred probe cases, the “device initialised in time” check should
> likely be done at late_initcall_sync, rather than late_initcall.
>
> This implies that any such check performed before late_initcall_sync
> does not reflect a valid state, as it cannot distinguish between “not
> present” and “deferred”.
>
> Therefore, I think the TPM check in IMA should be performed at
> late_initcall_sync.
>
>
> Am I missing something?
In ima_init() you short circuit out, when called by late_initcall(), if the TPM
hasn't been initialized. So the rest of the ima_init() isn't called. Roughly
something like this (needs some cleanup):
int __init ima_init(void)
{
static int first = 1;
int rc;
if (ima_tpm_chip)
return 0;
ima_tpm_chip = tpm_default_chip();
if (!ima_tpm_chip && first) {
pr_info("No TPM chip found, deferring te late_initcall_sync()\n");
first = 0;
return 0;
}
The rest of the code remains the same.
Mimi
^ permalink raw reply
* Re: [RFC PATCH 1/4] security: ima: move ima_init into late_initcall_sync
From: Yeoreum Yun @ 2026-04-21 14:09 UTC (permalink / raw)
To: Mimi Zohar
Cc: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm, paul, jmorris, serge, roberto.sassu,
dmitry.kasatkin, eric.snowberg, peterhuewe, jarkko, jgg,
sudeep.holla, maz, oupton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will
In-Reply-To: <d6bcc9ef98a1e86887c5a79ff2822e70b5534343.camel@linux.ibm.com>
Hi Mimi,
> On Tue, 2026-04-21 at 13:50 +0100, Yeoreum Yun wrote:
> > Hi Mimi,
> >
> > > On Fri, 2026-04-17 at 18:57 +0100, Yeoreum Yun wrote:
> > > > To generate the boot_aggregate log in the IMA subsystem with TPM PCR values,
> > > > the TPM driver must be built as built-in and
> > > > must be probed before the IMA subsystem is initialized.
> > > >
> > > > However, when the TPM device operates over the FF-A protocol using
> > > > the CRB interface, probing fails and returns -EPROBE_DEFER if
> > > > the tpm_crb_ffa device — an FF-A device that provides the communication
> > > > interface to the tpm_crb driver — has not yet been probed.
> > > >
> > > > To ensure the TPM device operating over the FF-A protocol with
> > > > the CRB interface is probed before IMA initialization,
> > > > the following conditions must be met:
> > > >
> > > > 1. The corresponding ffa_device must be registered,
> > > > which is done via ffa_init().
> > > >
> > > > 2. The tpm_crb_driver must successfully probe this device via
> > > > tpm_crb_ffa_init().
> > > >
> > > > 3. The tpm_crb driver using CRB over FF-A can then
> > > > be probed successfully. (See crb_acpi_add() and
> > > > tpm_crb_ffa_init() for reference.)
> > > >
> > > > Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
> > > > all registered with device_initcall, which means crb_acpi_driver_init() may
> > > > be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
> > > >
> > > > When this occurs, probing the TPM device is deferred.
> > > > However, the deferred probe can happen after the IMA subsystem
> > > > has already been initialized, since IMA initialization is performed
> > > > during late_initcall, and deferred_probe_initcall() is performed
> > > > at the same level.
> > > >
> > > > To resolve this, move ima_init() into late_inicall_sync level
> > > > so that let IMA not miss TPM PCR value when generating boot_aggregate
> > > > log though TPM device presents in the system.
> > > >
> > > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> > >
> > > IMA should be initialized as early as possible. I'm really hesitant to defer
> > > ima_init() to late_initcall_sync() for systems that the TPM is currently
> > > initialized in time. For these systems, continue initializing IMA at
> > > late_initcall(). As a compromise for those systems that the TPM isn't properly
> > > initialized in time, define and instantiate the late_initcall_sync().
> > >
> > > ima_init() would need to differentiate between the late_initcall and
> > > late_initcall_sync. On late_initcall(), instead of saying "No TPM chip found,
> > > activating TPM-bypass!", it should say "No TPM chip found, deferring to
> > > late_initcall_sync" or something similar.
> >
> > But can we really move those initialisations to be called again?
> >
> > I am referring to functions such as ima_init_crypto(),
> > ima_add_boot_aggregate(), and ima_measure_critical_data() in ima_init()—
> > first without TPM, and then a second time once TPM becomes available.
> > I don’t think that approach would work.
> >
> > In other words, unless tpm_default_chip() can differentiate between a TPM
> > device that is deferred and one that does not exist, we cannot distinguish
> > between the “defer” case and “-EEXIST”.
> >
> > It might be possible if the TPM core tracked the state when a driver returns
> > -EPROBE_DEFER, but I am not sure that is the right approach.
> > For deferred probe cases, the “device initialised in time” check should
> > likely be done at late_initcall_sync, rather than late_initcall.
> >
> > This implies that any such check performed before late_initcall_sync
> > does not reflect a valid state, as it cannot distinguish between “not
> > present” and “deferred”.
> >
> > Therefore, I think the TPM check in IMA should be performed at
> > late_initcall_sync.
> >
> >
> > Am I missing something?
>
> In ima_init() you short circuit out, when called by late_initcall(), if the TPM
> hasn't been initialized. So the rest of the ima_init() isn't called. Roughly
> something like this (needs some cleanup):
>
> int __init ima_init(void)
> {
> static int first = 1;
> int rc;
>
> if (ima_tpm_chip)
> return 0;
>
> ima_tpm_chip = tpm_default_chip();
> if (!ima_tpm_chip && first) {
> pr_info("No TPM chip found, deferring te late_initcall_sync()\n");
> first = 0;
> return 0;
> }
I see. then I'll respin in v2.
Thanks!
--
Sincerely,
Yeoreum Yun
^ permalink raw reply
* Re: [PATCH AUTOSEL 7.0-6.18] ima: Define and use a digest_size field in the ima_algo_desc structure
From: Mimi Zohar @ 2026-04-21 18:49 UTC (permalink / raw)
To: Sasha Levin, patches, stable
Cc: Roberto Sassu, dmitry.kasatkin, paul, jmorris, serge,
linux-integrity, linux-security-module, linux-kernel
In-Reply-To: <20260420132314.1023554-102-sashal@kernel.org>
On Mon, 2026-04-20 at 09:18 -0400, Sasha Levin wrote:
> From: Roberto Sassu <roberto.sassu@huawei.com>
>
> [ Upstream commit a74d7197ebe5b1b8028911d47e78c119d9aaf193 ]
>
> Add the digest_size field to the ima_algo_desc structure to determine the
> digest size from the correct source.
>
> If the hash algorithm is among allocated PCR banks, take the value from the
> TPM bank info (equal to the value from the crypto subsystem if the TPM
> algorithm is supported by it; otherwise, not exceding the size of the
> digest buffer in the tpm_digest structure, used by IMA).
>
> If the hash algorithm is SHA1, use the predefined value. Lastly, if the
> hash algorithm is the default one but not among the PCR banks, take the
> digest size from the crypto subsystem (the default hash algorithm is
> checked when parsing the ima_hash= command line option).
>
> Finally, use the new information to correctly show the template digest in
> ima_measurements_show() and ima_ascii_measurements_show().
>
> Link: https://github.com/linux-integrity/linux/issues/14
> Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
>
> LLM Generated explanations, may be completely bogus:
>
> Now I have complete information. Let me provide the final analysis.
>
> ## Phase 1: Commit Message Forensics
>
> ### Step 1.1: Subject Line
> **Record:** Subsystem: `ima:` (Integrity Measurement Architecture, a
> security subsystem). Action verb: "Define and use" - sounds like
> enhancement, but functionally equivalent to "fix digest size source".
> One-line summary: Add a digest_size field to ima_algo_desc for accurate
> template digest output.
>
> ### Step 1.2: Tags
> **Record:**
> - `Link: https://github.com/linux-integrity/linux/issues/14` (bug
> tracker for the linux-integrity subsystem)
> - `Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>` (author)
> - `Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>` (IMA maintainer -
> applied the patch)
> - No `Fixes:`, no `Cc: stable`, no `Reported-by:` tag.
>
> ### Step 1.3: Commit Body Analysis
> **Record:** The message describes three cases for digest size:
> 1. TPM bank-allocated algos: take from TPM bank info (which may differ
> from crypto subsystem size)
> 2. SHA1: use predefined value
> 3. Default hash algo not among banks: use crypto subsystem's size
>
> Author's framing is additive/improvement ("Add the ... field"), but the
> Link points to GitHub issue #14 titled "Out of bound when creating per-
> algo measurement list interfaces" - describing a KASAN out-of-bounds
> read when TPM has unsupported algorithms (e.g., SHA3_256).
>
> ### Step 1.4: Hidden Bug Fix Detection
> **Record:** This IS a hidden bug fix. The old code used
> `hash_digest_size[algo]` where `algo` can be `HASH_ALGO__LAST` (for
> unsupported TPM algos). Since `hash_digest_size` is declared
> `[HASH_ALGO__LAST]`, that access is out-of-bounds. The new code uses the
> TPM bank's `digest_size` (always valid) or a known constant.
>
> ## Phase 2: Diff Analysis
>
> ### Step 2.1: Inventory
> **Record:** 3 files changed:
> - `security/integrity/ima/ima.h` (+1)
> - `security/integrity/ima/ima_crypto.c` (+6)
> - `security/integrity/ima/ima_fs.c` (+6/-12)
>
> Total: 13 insertions, 12 deletions. Scope: single-subsystem surgical
> change.
>
> ### Step 2.2-2.3: Code Flow and Bug Mechanism
> **Record:** Bug category: **Out-of-bounds read** (KASAN-detectable).
>
> Before fix: `ima_putc(m, e->digests[algo_idx].digest,
> hash_digest_size[algo])` where `algo = ima_algo_array[algo_idx].algo`.
> If the TPM has an algorithm not supported by the kernel's crypto
> subsystem (e.g., SHA3_256 which was not yet in `tpm2_hash_map`), `algo
> == HASH_ALGO__LAST`, and `hash_digest_size[HASH_ALGO__LAST]` is an OOB
> read of the `[HASH_ALGO__LAST]`-sized array.
>
> After fix: `ima_putc(m, e->digests[algo_idx].digest,
> ima_algo_array[algo_idx].digest_size)`. `digest_size` is populated from
> `tpm_bank_info.digest_size` (which is filled via `tpm2_pcr_read` for
> unknown algos, or `hash_digest_size[crypto_algo]` for known ones),
> `SHA1_DIGEST_SIZE`, or `hash_digest_size[ima_hash_algo]` - all safe
> indexes.
>
> ### Step 2.4: Fix Quality
> **Record:** Fix is obviously correct, minimal, and well-contained. The
> new `digest_size` field is populated once during init (`__init`), then
> only read later. Regression risk is low - the change is semantically
> equivalent to the old code when the TPM algo is supported, and correct
> when it isn't.
>
> ## Phase 3: Git History
>
> ### Step 3.1-3.2: Blame and Fixes target
> **Record:** The buggy line `ima_putc(m, e->digests[algo_idx].digest,
> hash_digest_size[algo])` was introduced by commit `9fa8e76250082a`
> ("ima: add crypto agility support for template-hash algorithm", by
> Enrico Bravi, merged in v6.10). This code is present in every stable
> tree from v6.10 onwards (so 6.12.y and newer).
>
> ### Step 3.3: Related Commits
> **Record:** Companion commit `d7bd8cf0b348d` ("ima_fs: Correctly create
> securityfs files for unsupported hash algos") was applied 12 days after
> this one, sharing the same `Link:` to issue #14. That commit has an
> explicit `Fixes: 9fa8e7625008` tag and includes a KASAN dump showing
> `create_securityfs_measurement_lists+0x396/0x440` OOB in
> `hash_algo_name`. The two commits address two sides of the same bug:
> `a74d7197ebe5b` fixes OOB in `hash_digest_size[algo]` (runtime, at file
> read), `d7bd8cf0b348d` fixes OOB in `hash_algo_name[algo]` (boot, at
> file creation).
>
> ### Step 3.4: Author Context
> **Record:** Roberto Sassu is a long-term IMA contributor. Mimi Zohar is
> the IMA subsystem maintainer who merged the patch.
>
> ### Step 3.5: Dependencies
> **Record:** The fix depends on `tpm_bank_info.digest_size` being
> available, which has existed since commit `879b589210a9a` (2019). No new
> dependencies. Applies to any stable tree containing `9fa8e76250082a`
> (v6.10+).
>
> ## Phase 4: Mailing List Research
>
> ### Step 4.1-4.4: Patch Discussion
> **Record:**
> - `b4 dig -c a74d7197ebe5b` found single v1 submission at `https://lore.
> kernel.org/all/20260225125301.87996-1-roberto.sassu@huaweicloud.com/`
> - Discussion thread contains 3 messages from Mimi Zohar (maintainer) and
> Roberto Sassu. Mimi requested title rename and asked for a note about
> the design change (from crypto subsystem's digest size to TPM's).
> - No explicit stable nomination, no mention of KASAN in discussion
> thread itself.
> - GitHub issue #14 (referenced via Link: tag) explicitly documents the
> OOB bug this is fixing: "If a TPM algorithm is not supported the PCR
> bank info is initialized with HASH_ALGO__LAST, which passed to
> hash_algo_name[] causes an out of bound."
> - No v2, applied as single revision.
>
> ### Step 4.5: Stable Discussion
> **Record:** No prior stable mailing list discussion found for this
> specific commit.
>
> ## Phase 5: Code Semantic Analysis
>
> ### Step 5.1-5.4: Call Paths
> **Record:** `ima_measurements_show()` is called when a userspace process
> reads `/sys/kernel/security/ima/binary_runtime_measurements*`.
> `ima_ascii_measurements_show()` similarly for ASCII files. These files
> are readable by root. The path is reachable from userspace via a simple
> `read()` syscall against the securityfs files. `ima_init_crypto()` is
> called once at boot via initcall.
>
> ### Step 5.5: Similar Patterns
> **Record:** The sister commit `d7bd8cf0b348d` addresses the same pattern
> (`hash_algo_name[algo]` with `algo == HASH_ALGO__LAST`) in the file-
> creation path.
>
> ## Phase 6: Stable Tree Cross-Reference
>
> ### Step 6.1-6.3: Applicability
> **Record:**
> - Buggy code exists in 6.12.y (verified via `git blame stable-
> push/linux-6.12.y` showing line 184 originated from 9fa8e76250082a).
> Also in 6.15, 6.17, 6.18, 6.19, 7.0.
> - 6.1.y and 6.6.y don't have the crypto agility code
> (`hash_digest_size[algo]` usage) - the fix is NOT applicable/needed
> there. 6.6.y uses `TPM_DIGEST_SIZE`.
> - Backport difficulty to 6.12.y: minor rework needed (ima_algo_array
> allocation uses `kcalloc` instead of `kzalloc_objs` in newer tree, but
> that's not affected by this patch - the field addition and assignments
> apply straightforwardly).
> - Neither this commit nor `d7bd8cf0b348d` is yet in 6.12.y (verified via
> `git log stable-push/linux-6.12.y`).
>
> ## Phase 7: Subsystem Context
>
> ### Step 7.1-7.2
> **Record:** Subsystem: IMA (security/integrity/ima/). Criticality:
> IMPORTANT - used for measured boot/attestation on enterprise/embedded
> systems. Activity: active subsystem with regular fixes. The code is only
> reachable when CONFIG_IMA is enabled AND a TPM is present, further
> narrowing impact to TPM-equipped systems.
>
> ## Phase 8: Impact and Risk
>
> ### Step 8.1: Affected Users
> **Record:** Users with IMA enabled + TPM 2.0 chip that exposes an
> algorithm not in the kernel's `tpm2_hash_map`. The KASAN dump in
> d7bd8cf0b348d shows this was hit on real hardware (SHA3_256-capable
> TPM).
>
> ### Step 8.2: Trigger
> **Record:** The secondary OOB fixed by THIS commit
> (hash_digest_size[HASH_ALGO__LAST]) triggers when:
> 1. A TPM exposes an unsupported algorithm (e.g., SHA3_256)
> 2. A user (root) reads the unsupported-algo measurements file
> Root privilege required - not a remote attack vector, but reproducible
> with specific hardware. The primary OOB (in create_securityfs) hits
> every boot with such TPMs, which is what the KASAN report showed.
>
> ### Step 8.3: Failure Mode
> **Record:** Out-of-bounds read from kernel memory. Under KASAN: reported
> as BUG. Without KASAN: may return garbage digest size, which could cause
> excessive data to be read from `e->digests[algo_idx].digest` (a fixed-
> size `[TPM2_MAX_DIGEST_SIZE]` buffer) or leak a few bytes past the
> `hash_digest_size` array. Severity: **MEDIUM-HIGH** (OOB read is KASAN-
> reportable security-relevant behavior, not a guaranteed crash without
> KASAN but can leak info or cause incorrect behavior).
>
> ### Step 8.4: Risk vs Benefit
> **Record:**
> - **Benefit: MEDIUM** - Fixes one half of a KASAN-reportable OOB read
> with real-hardware reproducer.
> - **Risk: LOW** - 13-line structural change, all within the IMA init
> path + two show functions, no change of external behavior for
> supported TPM algos.
> - **Ratio: Favorable for backport** - but only valuable when paired with
> d7bd8cf0b348d (the boot-time crash fix).
>
> ## Phase 9: Final Synthesis
>
> ### Step 9.1-9.4: Evidence Summary
>
> **For backport:**
> - Small, contained (13/12 lines, 3 files)
> - Fixes real OOB read (hash_digest_size[HASH_ALGO__LAST])
> - Obviously correct - reviewed by IMA maintainer (Mimi Zohar)
> - Low regression risk
> - Reachable from userspace (root reads securityfs file)
> - Bug has real-hardware reproducer (SHA3_256 TPMs)
> - Companion commit d7bd8cf0b348d has `Fixes:` tag and will be auto-
> selected; backporting only d7bd8cf0b348d leaves a latent OOB in the
> read path
>
> **Against backport:**
> - No explicit `Fixes:` tag, no `Cc: stable`
> - Framed as enhancement, not bug fix
> - Alone doesn't fix the primary crash (boot-time OOB in
> `create_securityfs_measurement_lists`) - that's d7bd8cf0b348d
> - Design change (TPM's size vs crypto's size) noted by maintainer in
> review
>
> **Exception Category:** Not a device ID/quirk/DT/build/doc. Standard bug
> fix evaluation.
>
> **Stable Rules Check:**
> 1. Obviously correct: YES (reviewed, simple struct field addition + safe
> sources)
> 2. Fixes real bug: YES (OOB read)
> 3. Important issue: MEDIUM (KASAN-reportable OOB with real hardware)
> 4. Small and contained: YES (13/12 lines)
> 5. No new features/APIs: YES (internal struct field, not user-visible)
> 6. Applies to stable: YES (6.12.y+ with minor/no conflicts)
>
> ## Verification
>
> - [Phase 1] Parsed tags: no Fixes:, no Cc: stable, has `Link:
> github.com/linux-integrity/linux/issues/14`
> - [Phase 1] Hidden bug fix confirmed: commit uses additive language but
> eliminates OOB read
> - [Phase 2] Diff analysis: `git show a74d7197ebe5b` confirmed +13/-12
> across 3 files; key change is replacing `hash_digest_size[algo]` with
> `ima_algo_array[algo_idx].digest_size`
> - [Phase 3] `git blame stable-push/linux-6.12.y
> security/integrity/ima/ima_fs.c`: buggy line 184 was introduced by
> 9fa8e76250082a (v6.10)
> - [Phase 3] `git show 9fa8e76250082`: confirmed merged in v6.10
> (2024-04-12)
> - [Phase 3] Found companion commit d7bd8cf0b348d sharing the same GitHub
> issue link
> - [Phase 3] Verified `include/linux/tpm.h` defines
> `tpm_bank_info.digest_size` (dependency satisfied in all target stable
> trees since 2019 via commit 879b589210a9a)
> - [Phase 4] `b4 dig -c a74d7197ebe5b`: found single v1 submission
> - [Phase 4] `b4 dig -c a74d7197ebe5b -a`: only v1, no earlier revisions
> - [Phase 4] `b4 dig -c a74d7197ebe5b -w`: maintainer Mimi Zohar was a
> recipient
> - [Phase 4] Read `/tmp/thread.mbx`: confirmed maintainer review, no
> stable nomination, no KASAN mention in thread
> - [Phase 4] WebFetch github issue #14: confirmed OOB bug rationale
> - [Phase 4] WebFetch marc.info original patch: confirmed patch content
> matches commit
> - [Phase 5] Verified `ima_measurements_show` is reachable via read() on
> `/sys/kernel/security/ima/*_runtime_measurements*`
> - [Phase 6] `git show stable-push/linux-6.12.y:.../ima_fs.c`: confirmed
> buggy line present at 184
> - [Phase 6] `git show stable-push/linux-6.6.y:.../ima_fs.c`: uses
> `TPM_DIGEST_SIZE`, no crypto agility, bug doesn't exist there
> - [Phase 6] `git show stable-push/linux-6.1.y`: ima_fs.c does not have
> the buggy code
> - [Phase 6] `git log stable-push/linux-6.12.y`: neither this commit nor
> d7bd8cf0b348d is yet in 6.12.y
> - [Phase 8] Failure mode: OOB read of
> `hash_digest_size[HASH_ALGO__LAST]` - triggered by reading per-algo
> measurement file on TPM with unsupported algo
> - UNVERIFIED: Whether d7bd8cf0b348d has been auto-selected by Fixes:-tag
> tooling; whether user-visible symptoms (without KASAN) would be
> observable in the field.
>
> ## Conclusion
>
> This commit is a small, surgical fix for a real out-of-bounds read bug
> that affects stable trees from v6.12 onwards. While the commit message
> frames it as an "add a field" improvement rather than a bug fix, the
> code change explicitly eliminates an OOB read in the user-reachable path
> `ima_measurements_show()` / `ima_ascii_measurements_show()` when a TPM
> exposes an algorithm not supported by the kernel crypto subsystem. The
> companion commit `d7bd8cf0b348d` addresses the parallel boot-time OOB
> (in `create_securityfs_measurement_lists`) and has a `Fixes:` tag, so it
> will likely be auto-selected. If d7bd8cf0b348d reaches stable (as it
> should), this commit is needed to plug the remaining runtime OOB on the
> same hardware.
>
> **YES**
Thanks, Sasha!
The AI's conclusion is correct. This patch is needed when backporting commit
d7bd8cf0b348 ("ima_fs: Correctly create securityfs files for unsupported hash
algos") is correct.
Mimi
^ permalink raw reply
* Re: [PATCH RFC bpf-next 0/4] audit: Expose audit subsystem to BPF LSM programs via BPF kfuncs
From: Frederick Lawler @ 2026-04-21 21:07 UTC (permalink / raw)
To: Paul Moore, James Morris, Serge E. Hallyn, Eric Paris,
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Mickaël Salaün, Günther Noack
Cc: linux-kernel, linux-security-module, audit, bpf, linux-kselftest,
kernel-team
In-Reply-To: <20260311-bpf-auditd-send-message-v1-0-10a62db5c92f@cloudflare.com>
Hi folks,
I was accepted to speak a little bit about this patch series at Linux
Security Summit this May [1]. I'm going to use this opportunity to
re-iterate some of the motivation, what can be done today with BPF,
drawbacks, and wrap up with discussion topics. I'd love to hear feedback
from audit, BPF, and security folks to work towards a viable solution that
addresses shortcomings to allow for better integration with BPF.
Best,
Fred
[1]: https://lssna2026.sched.com/event/2KEc3/bridging-bpf-lsm-and-the-linux-audit-subsystem-frederick-lawler-cloudflare?iframe=yes&w=100%&sidebar=yes&bg=no
^ permalink raw reply
* Re: [PATCH RFC bpf-next 0/4] audit: Expose audit subsystem to BPF LSM programs via BPF kfuncs
From: Alexei Starovoitov @ 2026-04-21 21:12 UTC (permalink / raw)
To: Frederick Lawler
Cc: Paul Moore, James Morris, Serge E. Hallyn, Eric Paris,
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Mickaël Salaün, Günther Noack, LKML,
LSM List, audit, bpf, open list:KERNEL SELFTEST FRAMEWORK,
kernel-team
In-Reply-To: <aefnIw1Tx_2r5nkS@CMGLRV3>
On Tue, Apr 21, 2026 at 2:07 PM Frederick Lawler <fred@cloudflare.com> wrote:
>
> Hi folks,
>
> I was accepted to speak a little bit about this patch series at Linux
> Security Summit this May [1]. I'm going to use this opportunity to
> re-iterate some of the motivation, what can be done today with BPF,
> drawbacks, and wrap up with discussion topics. I'd love to hear feedback
> from audit, BPF, and security folks to work towards a viable solution that
> addresses shortcomings to allow for better integration with BPF.
I don't think any bpf folks will be there.
Also giving a talk about it doesn't make it acceptable.
It's still Nack.
^ permalink raw reply
* Re: [PATCH RFC bpf-next 0/4] audit: Expose audit subsystem to BPF LSM programs via BPF kfuncs
From: Paul Moore @ 2026-04-21 22:10 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Frederick Lawler, James Morris, Serge E. Hallyn, Eric Paris,
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Mickaël Salaün, Günther Noack, LKML,
LSM List, audit, bpf, open list:KERNEL SELFTEST FRAMEWORK,
kernel-team
In-Reply-To: <CAADnVQJQxa+fHM9X8COc60ZMcxF0DMhWbtArg_gPynpbbg55TQ@mail.gmail.com>
On Tue, Apr 21, 2026 at 5:12 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
> On Tue, Apr 21, 2026 at 2:07 PM Frederick Lawler <fred@cloudflare.com> wrote:
> >
> > Hi folks,
> >
> > I was accepted to speak a little bit about this patch series at Linux
> > Security Summit this May [1]. I'm going to use this opportunity to
> > re-iterate some of the motivation, what can be done today with BPF,
> > drawbacks, and wrap up with discussion topics. I'd love to hear feedback
> > from audit, BPF, and security folks to work towards a viable solution that
> > addresses shortcomings to allow for better integration with BPF.
>
> I don't think any bpf folks will be there.
> Also giving a talk about it doesn't make it acceptable.
I think it's valid to have a discussion with the LSS folks as they are
the ones who will most likely be interested in using the
functionality. From my perspective there is still value in validating
the basic ideas in Fred's patchset and checking the value amongst the
LSS audience.
> It's still Nack.
Based solely on the diffstat and a quick look, this appears to be an
LSM patchset, not necessarily a BPF patchset; yes, there are kfuncs,
but they are LSM/audit kfuncs and not core BPF functionality.
Regardless, I want to see how the LSS presentation is received before
worrying about this too much, but your NACK has been noted.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH RFC bpf-next 0/4] audit: Expose audit subsystem to BPF LSM programs via BPF kfuncs
From: Alexei Starovoitov @ 2026-04-21 22:14 UTC (permalink / raw)
To: Paul Moore, Linus Torvalds
Cc: Frederick Lawler, James Morris, Serge E. Hallyn, Eric Paris,
Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Mickaël Salaün, Günther Noack, LKML,
LSM List, audit, bpf, open list:KERNEL SELFTEST FRAMEWORK,
kernel-team
In-Reply-To: <CAHC9VhSo-M1wK2s2P0B+2F0pJqNguW7Kj-g63anp1xCMSBLa6Q@mail.gmail.com>
On Tue, Apr 21, 2026 at 3:10 PM Paul Moore <paul@paul-moore.com> wrote:
>
>
> > It's still Nack.
>
> Based solely on the diffstat and a quick look, this appears to be an
> LSM patchset, not necessarily a BPF patchset; yes, there are kfuncs,
> but they are LSM/audit kfuncs and not core BPF functionality.
> Regardless, I want to see how the LSS presentation is received before
> worrying about this too much, but your NACK has been noted.
Paul,
told you countless times LSM cannot touch BPF bits without
explicit Ack.
So, no, you cannot add bpf kfuncs in random places in the kernel
And, no, you cannot call bpf internals through bpf_map_ops, etc.
^ permalink raw reply
* Re: [PATCH RFC bpf-next 0/4] audit: Expose audit subsystem to BPF LSM programs via BPF kfuncs
From: Paul Moore @ 2026-04-21 22:49 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Linus Torvalds, Frederick Lawler, James Morris, Serge E. Hallyn,
Eric Paris, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Mickaël Salaün, Günther Noack, LKML,
LSM List, audit, bpf, open list:KERNEL SELFTEST FRAMEWORK,
kernel-team
In-Reply-To: <CAADnVQL33TOWFmxcWod3BCgmMXSQ=cEp6NCcxgQaJL0C7+Z9zA@mail.gmail.com>
On Tue, Apr 21, 2026 at 6:15 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
> On Tue, Apr 21, 2026 at 3:10 PM Paul Moore <paul@paul-moore.com> wrote:
> >
> > > It's still Nack.
> >
> > Based solely on the diffstat and a quick look, this appears to be an
> > LSM patchset, not necessarily a BPF patchset; yes, there are kfuncs,
> > but they are LSM/audit kfuncs and not core BPF functionality.
> > Regardless, I want to see how the LSS presentation is received before
> > worrying about this too much, but your NACK has been noted.
>
> Paul,
>
> told you countless times LSM cannot touch BPF bits without
> explicit Ack.
Based on a quick glance it doesn't appear that Fred's patches touch
BPF bits, they simply supply kfuncs for users to use in their BPF
programs.
> So, no, you cannot add bpf kfuncs in random places in the kernel
I see plenty of places outside of kernel/bpf that define kfuncs.
> And, no, you cannot call bpf internals through bpf_map_ops, etc.
It doesn't appear that Fred is doing that in his patches.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH RFC bpf-next 0/4] audit: Expose audit subsystem to BPF LSM programs via BPF kfuncs
From: Alexei Starovoitov @ 2026-04-21 23:08 UTC (permalink / raw)
To: Paul Moore
Cc: Linus Torvalds, Frederick Lawler, James Morris, Serge E. Hallyn,
Eric Paris, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Mickaël Salaün, Günther Noack, LKML,
LSM List, audit, bpf, open list:KERNEL SELFTEST FRAMEWORK,
kernel-team
In-Reply-To: <CAHC9VhSKvC+p5j5Pe1YKB-=vRkRA81K3kp97Q6-H5K+kvYa0AQ@mail.gmail.com>
On Tue, Apr 21, 2026 at 3:50 PM Paul Moore <paul@paul-moore.com> wrote:
>
> On Tue, Apr 21, 2026 at 6:15 PM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> > On Tue, Apr 21, 2026 at 3:10 PM Paul Moore <paul@paul-moore.com> wrote:
> > >
> > > > It's still Nack.
> > >
> > > Based solely on the diffstat and a quick look, this appears to be an
> > > LSM patchset, not necessarily a BPF patchset; yes, there are kfuncs,
> > > but they are LSM/audit kfuncs and not core BPF functionality.
> > > Regardless, I want to see how the LSS presentation is received before
> > > worrying about this too much, but your NACK has been noted.
> >
> > Paul,
> >
> > told you countless times LSM cannot touch BPF bits without
> > explicit Ack.
>
> Based on a quick glance it doesn't appear that Fred's patches touch
> BPF bits, they simply supply kfuncs for users to use in their BPF
> programs.
>
> > So, no, you cannot add bpf kfuncs in random places in the kernel
>
> I see plenty of places outside of kernel/bpf that define kfuncs.
We discussed this already.
All those places were explicitly acked by BPF maintainers.
Every time somebody adds a kfunc it breaks safety, because
people don't read or don't understand Documentation/bpf/kfuncs.rst.
kfuncs are not export_symbol.
Object ownership model needs to be thought through.
Calling context needs to be analyzed and so on.
Just because something "works for me" it doesn't mean
that it's safe.
^ permalink raw reply
* Re: [PATCH] lsm: Fix the crash issue in xfrm_decode_session
From: Feng Yang @ 2026-04-22 6:39 UTC (permalink / raw)
To: stephen.smalley.work
Cc: jmorris, linux-kernel, linux-security-module, paul, serge,
yangfeng59949
In-Reply-To: <CAEjxPJ6jPh9_P=56VfAhGQG-Y=njosFuV_Kys9kzhkm7PxRPLg@mail.gmail.com>
On Mon, 13 Apr 2026 13:39:18 -0400, Stephen Smalley wrote:
[...]
> > This BUG_ON was first mentioned in [1], but I could not find any explanatory record of why this check is needed.
> >
> > [1] https://lore.kernel.org/all/Pine.LNX.4.64.0607122149070.573@d.namei/
> >
> > In the existing LSM_HOOK_INIT(xfrm_decode_session, selinux_xfrm_decode_session),
> > when the `ckall` parameter of the `selinux_xfrm_decode_session` function is 0,
> > it can only return 0 and will not trigger BUG_ON.
> > Therefore, remove the BUG_ON check to fix this issue.
> >
> > Reported-by: Kaiyan Mei <M202472210@hust.edu.cn>
> > Reported-by: Yinhao Hu <dddddd@hust.edu.cn>
> > Closes: https://lore.kernel.org/all/4c4d04ba.6c12b.19c039b69e6.Coremail.kaiyanm@hust.edu.cn/
> > Signed-off-by: Feng Yang <yangfeng@kylinos.cn>
>
> Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
>
> With the proviso that we likely ought to follow up with a clean-up
> that introduces a separate skb_classify_flow LSM hook that returns
> void so we don't awkwardly ignore errors below and defer handling to
> the individual security module.
Thank you for your review. Should the follow-up cleanup optimization for
adding a separate skb_classify_flow hook be submitted after this patch is merged?
> > ---
> > security/security.c | 5 +----
> > 1 file changed, 1 insertion(+), 4 deletions(-)
> >
> > diff --git a/security/security.c b/security/security.c
> > index 67af9228c4e9..198f650070da 100644
> > --- a/security/security.c
> > +++ b/security/security.c
> > @@ -4991,10 +4991,7 @@ int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
> >
> > void security_skb_classify_flow(struct sk_buff *skb, struct flowi_common *flic)
> > {
> > - int rc = call_int_hook(xfrm_decode_session, skb, &flic->flowic_secid,
> > - 0);
> > -
> > - BUG_ON(rc);
> > + call_int_hook(xfrm_decode_session, skb, &flic->flowic_secid, 0);
> > }
> > EXPORT_SYMBOL(security_skb_classify_flow);
> > #endif /* CONFIG_SECURITY_NETWORK_XFRM */
> > --
> > 2.43.0
^ permalink raw reply
* Re: [PATCH] apparmor: Fix two bugs of aa_setup_dfa_engine's fail handling
From: GONG Ruiqi @ 2026-04-22 7:03 UTC (permalink / raw)
To: John Johansen, Paul Moore, James Morris, Serge E . Hallyn
Cc: apparmor, linux-security-module, linux-kernel, lujialin4
In-Reply-To: <20260403035119.2132418-1-gongruiqi1@huawei.com>
Kindly ping.
On 4/3/2026 11:51 AM, GONG Ruiqi wrote:
> First, aa_dfa_unpack returns ERR_PTR not NULL when it fails, but
> aa_put_dfa only checks NULL for its input, which would cause invalid
> memory access in aa_put_dfa. Set nulldfa to NULL explicitly to fix that.
>
> Second, aa_put_pdb calls aa_pdb_free_kref -> aa_free_pdb -> aa_put_dfa,
> i.e. it will free nullpdb->dfa. But there's another aa_put_dfa(nulldfa)
> after aa_put_pdb(nullpdb), which would cause double free. Remove that
> redundant aa_put_dfa to fix that.
>
> Fixes: 98b824ff8984 ("apparmor: refcount the pdb")
> Signed-off-by: GONG Ruiqi <gongruiqi1@huawei.com>
> ---
> security/apparmor/lsm.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
> index c1d42fc72fdb..be82ec1b9fd9 100644
> --- a/security/apparmor/lsm.c
> +++ b/security/apparmor/lsm.c
> @@ -2465,6 +2465,7 @@ static int __init aa_setup_dfa_engine(void)
> TO_ACCEPT2_FLAG(YYTD_DATA32));
> if (IS_ERR(nulldfa)) {
> error = PTR_ERR(nulldfa);
> + nulldfa = NULL;
> goto fail;
> }
> nullpdb->dfa = aa_get_dfa(nulldfa);
> @@ -2486,7 +2487,6 @@ static int __init aa_setup_dfa_engine(void)
>
> fail:
> aa_put_pdb(nullpdb);
> - aa_put_dfa(nulldfa);
> nullpdb = NULL;
> nulldfa = NULL;
> stacksplitdfa = NULL;
^ permalink raw reply
* Re: [RFC PATCH 4/4] firmware: arm_ffa: check pkvm initailised when initailise ffa driver
From: Yeoreum Yun @ 2026-04-22 13:32 UTC (permalink / raw)
To: Sudeep Holla
Cc: Marc Zyngier, linux-security-module, linux-kernel,
linux-integrity, linux-arm-kernel, kvmarm, paul, jmorris, zohar,
roberto.sassu, dmitry.kasatkin, eric.snowberg, jarkko, oupton,
joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas, will,
sebastianene
In-Reply-To: <aec/YSxYO1bOhXhn@e129823.arm.com>
Hi All,
> > On Tue, Apr 21, 2026 at 07:57:43AM +0100, Yeoreum Yun wrote:
> >
> > [...]
> >
> > >
> > > Also, the FF-A initialization is not driven by a device probe, but rather
> > > happens as part of the bus registration itself,
> > > so it does not fit well with a device_link or probe deferral based approach.
> > >
> > > Instead, perhaps we could go with the idea I mentioned previously:
> > > either introduce a notifier, or create a pseudo ffa_device
> > > once pKVM initialization has completed, and
> > > then let the ffa driver perform the additional initialization from there.
> > >
> > > Am I missing something?
> > >
> >
> > In order to handle/cleanup some ugliness in interrupt management in the
> > FF-A driver, we may introduce DT node eventually. But it will take sometime.
>
> Unfortunately, I think this DT node wouldn't be helpful to solve
> this situation for dependency with the kvm misc device...
>
> IMHO, current situation, the notifier seems to good option. unless
> we make the initcall to recongise this dependency.
>
I think the best approach for now is to introduce a notifier to handle this situation.
If there are no further suggestions, I’ll send a v2 based on:
- https://lore.kernel.org/all/aeS4rAeVQ0yJIPYw@e129823.arm.com/
Thanks!
--
Sincerely,
Yeoreum Yun
^ permalink raw reply
* Re: [PATCH RFC bpf-next 0/4] audit: Expose audit subsystem to BPF LSM programs via BPF kfuncs
From: Paul Moore @ 2026-04-22 14:33 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Linus Torvalds, Frederick Lawler, James Morris, Serge E. Hallyn,
Eric Paris, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Mickaël Salaün, Günther Noack, LKML,
LSM List, audit, bpf, open list:KERNEL SELFTEST FRAMEWORK,
kernel-team
In-Reply-To: <CAADnVQJBOk8w89kj95M3GH-eFdC7njZt=zMEU=skB-DTb3k-bw@mail.gmail.com>
On Tue, Apr 21, 2026 at 7:08 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
> On Tue, Apr 21, 2026 at 3:50 PM Paul Moore <paul@paul-moore.com> wrote:
> > On Tue, Apr 21, 2026 at 6:15 PM Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> > > On Tue, Apr 21, 2026 at 3:10 PM Paul Moore <paul@paul-moore.com> wrote:
> > > >
> > > > > It's still Nack.
> > > >
> > > > Based solely on the diffstat and a quick look, this appears to be an
> > > > LSM patchset, not necessarily a BPF patchset; yes, there are kfuncs,
> > > > but they are LSM/audit kfuncs and not core BPF functionality.
> > > > Regardless, I want to see how the LSS presentation is received before
> > > > worrying about this too much, but your NACK has been noted.
> > >
> > > Paul,
> > >
> > > told you countless times LSM cannot touch BPF bits without
> > > explicit Ack.
> >
> > Based on a quick glance it doesn't appear that Fred's patches touch
> > BPF bits, they simply supply kfuncs for users to use in their BPF
> > programs.
> >
> > > So, no, you cannot add bpf kfuncs in random places in the kernel
> >
> > I see plenty of places outside of kernel/bpf that define kfuncs.
>
> We discussed this already.
> All those places were explicitly acked by BPF maintainers.
Perhaps. However, we don't have to look further than your first
response in this thread to notice a prejudice against existing
in-kernel security/auditing mechanisms that large numbers of users
rely on every day. While I'll continue to try working with you, and
encourage others to do the same, you've forced me into a position
where I need to consider sending patches to Linus that you've NACK'd.
I don't like it, it indicates a cultural breakdown and the formation
of rigid silos/fiefdoms within the kernel community, but I have a
responsibility to the other developers and users to represent and
advocate for their security needs.
> Every time somebody adds a kfunc it breaks safety, because
> people don't read or don't understand Documentation/bpf/kfuncs.rst.
> kfuncs are not export_symbol.
> Object ownership model needs to be thought through.
> Calling context needs to be analyzed and so on.
> Just because something "works for me" it doesn't mean
> that it's safe.
Unfortunately that isn't the review you provided Fred in this thread.
There were no comments about object ownership, calling context,
safety, etc., only a dismissive comment telling Fred to use something
else for logging. If you want to provide proper feedback, something
along the lines of Kumar's constructive review, I think Fred would
welcome that.
--
paul-moore.com
^ permalink raw reply
* [RFC PATCH v2 0/4] fix FF-A call failed with pKVM when ff-a driver is built-in
From: Yeoreum Yun @ 2026-04-22 16:24 UTC (permalink / raw)
To: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm
Cc: paul, jmorris, serge, zohar, roberto.sassu, dmitry.kasatkin,
eric.snowberg, jarkko, jgg, sudeep.holla, maz, oupton, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, will, noodles,
sebastianene, Yeoreum Yun
commit 0e0546eabcd6 ("firmware: arm_ffa: Change initcall level of ffa_init() to rootfs_initcall")
changed the initcall level of ffa_init() to rootfs_initcall to address
an issue where IMA could not properly recognize the TPM device
when FF-A driver is built as built-in.
However, this introduces another problem: pKVM fails to handle FF-A calls
because it cannot trap the FFA_VERSION call invoked by ffa_init().
To ensure the TPM device is recognized when present in the system,
it is preferable to invoke again ima_init() at a later stage.
Deferred probing is resolved by deferred_probe_initcall(),
which runs at the late_initcall level.
Therefore, introduce an LSM initcall at late_initcall_sync and
invode ima_init() again to this level in case of TPM is probed yet
at the late_initcall stage.
With this change, revert the initcall level of ffa_init() back to
device_initcall. Additionally, to handle the case where ffa_init() runs
before kvm_init(), check whether pKVM has been initialized during ffa_init().
If not, defer initialization to prevent failures of FF-A calls
due to the inability to trap FFA_VERSION and FFA_RXTX_MAP in pKVM.
This patch is based on v7.0
Patch History
=============
from v1 to v2:
- add notifier to make ffa-driver pkvm initialised.
- modify to try initailisation again when IMA coudln't find proper TPM device.
- https://lore.kernel.org/all/20260417175759.3191279-1-yeoreum.yun@arm.com/#t
Yeoreum Yun (4):
security: ima: call ima_init() again at late_initcall_sync for defered
TPM
tpm: tpm_crb_ffa: revert defered_probed when tpm_crb_ffa is built-in
firmware: arm_ffa: revert ffa_init() initcall level to device_initcall
firmware: arm_ffa: check pkvm initailised when initailise ffa driver
arch/arm64/include/asm/virt.h | 11 +++++
arch/arm64/kvm/arm.c | 21 ++++++++
arch/arm64/kvm/pkvm.c | 2 +
drivers/char/tpm/tpm_crb_ffa.c | 18 ++-----
drivers/firmware/arm_ffa/common.h | 4 +-
drivers/firmware/arm_ffa/driver.c | 38 ++++++++++++++-
drivers/firmware/arm_ffa/smccc.c | 2 +-
include/linux/lsm_hooks.h | 2 +
security/integrity/ima/ima.h | 4 +-
security/integrity/ima/ima_init.c | 10 +++-
security/integrity/ima/ima_main.c | 76 +++++++++++++++++++++++------
security/integrity/ima/ima_policy.c | 3 ++
security/lsm_init.c | 13 ++++-
13 files changed, 163 insertions(+), 41 deletions(-)
base-commit: 028ef9c96e96197026887c0f092424679298aae8
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply
* [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Yeoreum Yun @ 2026-04-22 16:24 UTC (permalink / raw)
To: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm
Cc: paul, jmorris, serge, zohar, roberto.sassu, dmitry.kasatkin,
eric.snowberg, jarkko, jgg, sudeep.holla, maz, oupton, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, will, noodles,
sebastianene, Yeoreum Yun
In-Reply-To: <20260422162449.1814615-1-yeoreum.yun@arm.com>
To generate the boot_aggregate log in the IMA subsystem with TPM PCR values,
the TPM driver must be built as built-in and
must be probed before the IMA subsystem is initialized.
However, when the TPM device operates over the FF-A protocol using
the CRB interface, probing fails and returns -EPROBE_DEFER if
the tpm_crb_ffa device — an FF-A device that provides the communication
interface to the tpm_crb driver — has not yet been probed.
To ensure the TPM device operating over the FF-A protocol with
the CRB interface is probed before IMA initialization,
the following conditions must be met:
1. The corresponding ffa_device must be registered,
which is done via ffa_init().
2. The tpm_crb_driver must successfully probe this device via
tpm_crb_ffa_init().
3. The tpm_crb driver using CRB over FF-A can then
be probed successfully. (See crb_acpi_add() and
tpm_crb_ffa_init() for reference.)
Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
all registered with device_initcall, which means crb_acpi_driver_init() may
be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
When this occurs, probing the TPM device is deferred.
However, the deferred probe can happen after the IMA subsystem
has already been initialized, since IMA initialization is performed
during late_initcall, and deferred_probe_initcall() is performed
at the same level.
To resolve this, call ima_init() again at late_inicall_sync level
so that let IMA not miss TPM PCR value when generating boot_aggregate
log though TPM device presents in the system.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
include/linux/lsm_hooks.h | 2 +
security/integrity/ima/ima.h | 4 +-
security/integrity/ima/ima_init.c | 10 +++-
security/integrity/ima/ima_main.c | 76 +++++++++++++++++++++++------
security/integrity/ima/ima_policy.c | 3 ++
security/lsm_init.c | 13 ++++-
6 files changed, 87 insertions(+), 21 deletions(-)
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index d48bf0ad26f4..88fe105b7f00 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -166,6 +166,7 @@ enum lsm_order {
* @initcall_fs: LSM callback for fs_initcall setup, optional
* @initcall_device: LSM callback for device_initcall() setup, optional
* @initcall_late: LSM callback for late_initcall() setup, optional
+ * @initcall_late_sync: LSM callback for late_initcall_sync() setup, optional
*/
struct lsm_info {
const struct lsm_id *id;
@@ -181,6 +182,7 @@ struct lsm_info {
int (*initcall_fs)(void);
int (*initcall_device)(void);
int (*initcall_late)(void);
+ int (*initcall_late_sync)(void);
};
#define DEFINE_LSM(lsm) \
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 89ebe98ffc5e..75ee7ad184d0 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -62,6 +62,8 @@ extern int ima_hash_algo_idx __ro_after_init;
extern int ima_extra_slots __ro_after_init;
extern struct ima_algo_desc *ima_algo_array __ro_after_init;
+extern bool ima_initialised __ro_after_init;
+
extern int ima_appraise;
extern struct tpm_chip *ima_tpm_chip;
extern const char boot_aggregate_name[];
@@ -257,7 +259,7 @@ static inline void ima_measure_kexec_event(const char *event_name) {}
extern bool ima_canonical_fmt;
/* Internal IMA function definitions */
-int ima_init(void);
+int ima_init(bool late);
int ima_fs_init(void);
int ima_add_template_entry(struct ima_template_entry *entry, int violation,
const char *op, struct inode *inode,
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index a2f34f2d8ad7..c28c71090ad2 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -115,13 +115,19 @@ void __init ima_load_x509(void)
}
#endif
-int __init ima_init(void)
+int __init ima_init(bool late)
{
int rc;
ima_tpm_chip = tpm_default_chip();
- if (!ima_tpm_chip)
+ if (!ima_tpm_chip) {
+ if (!late) {
+ pr_info("Defer initialisation to the late_initcall_sync stage.\n");
+ return -EPROBE_DEFER;
+ }
+
pr_info("No TPM chip found, activating TPM-bypass!\n");
+ }
rc = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
if (rc)
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
index 1d6229b156fb..ac444ee600e2 100644
--- a/security/integrity/ima/ima_main.c
+++ b/security/integrity/ima/ima_main.c
@@ -38,6 +38,7 @@ int ima_appraise;
#endif
int __ro_after_init ima_hash_algo = HASH_ALGO_SHA1;
+bool ima_initialised __ro_after_init = false;
static int hash_setup_done;
static int ima_disabled __ro_after_init;
@@ -1237,6 +1238,35 @@ static int ima_kernel_module_request(char *kmod_name)
#endif /* CONFIG_INTEGRITY_ASYMMETRIC_KEYS */
+static int __init init_ima_core(bool late)
+{
+ int err;
+
+ if (ima_initialised)
+ return 0;
+
+ err = ima_init(late);
+ if (err == -EPROBE_DEFER)
+ return 0;
+
+ if (err && strcmp(hash_algo_name[ima_hash_algo],
+ CONFIG_IMA_DEFAULT_HASH) != 0) {
+ pr_info("Allocating %s failed, going to use default hash algorithm %s\n",
+ hash_algo_name[ima_hash_algo], CONFIG_IMA_DEFAULT_HASH);
+ hash_setup_done = 0;
+ hash_setup(CONFIG_IMA_DEFAULT_HASH);
+ err = ima_init(late);
+ }
+
+ if (!err) {
+ ima_update_policy_flags();
+ ima_initialised = true;
+ } else
+ ima_disabled = 1;
+
+ return err;
+}
+
static int __init init_ima(void)
{
int error;
@@ -1250,30 +1280,42 @@ static int __init init_ima(void)
ima_appraise_parse_cmdline();
ima_init_template_list();
hash_setup(CONFIG_IMA_DEFAULT_HASH);
- error = ima_init();
-
- if (error && strcmp(hash_algo_name[ima_hash_algo],
- CONFIG_IMA_DEFAULT_HASH) != 0) {
- pr_info("Allocating %s failed, going to use default hash algorithm %s\n",
- hash_algo_name[ima_hash_algo], CONFIG_IMA_DEFAULT_HASH);
- hash_setup_done = 0;
- hash_setup(CONFIG_IMA_DEFAULT_HASH);
- error = ima_init();
- }
-
- if (error)
- return error;
error = register_blocking_lsm_notifier(&ima_lsm_policy_notifier);
- if (error)
+ if (error) {
pr_warn("Couldn't register LSM notifier, error %d\n", error);
+ goto disable_ima;
+ }
- if (!error)
- ima_update_policy_flags();
+ error = init_ima_core(false);
+ if (error) {
+ unregister_blocking_lsm_notifier(&ima_lsm_policy_notifier);
+ goto disable_ima;
+ }
+
+ return 0;
+disable_ima:
+ ima_disabled = 1;
return error;
}
+static int __init late_init_ima(void)
+{
+ int err;
+
+ if (ima_disabled)
+ return 0;
+
+ err = init_ima_core(true);
+ if (err) {
+ unregister_blocking_lsm_notifier(&ima_lsm_policy_notifier);
+ ima_disabled = 1;
+ }
+
+ return err;
+}
+
static struct security_hook_list ima_hooks[] __ro_after_init = {
LSM_HOOK_INIT(bprm_check_security, ima_bprm_check),
LSM_HOOK_INIT(bprm_creds_for_exec, ima_bprm_creds_for_exec),
@@ -1321,4 +1363,6 @@ DEFINE_LSM(ima) = {
.blobs = &ima_blob_sizes,
/* Start IMA after the TPM is available */
.initcall_late = init_ima,
+ /* Start IMA late in case of probing TPM is deferred. */
+ .initcall_late_sync = late_init_ima,
};
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index bf2d7ba4c14a..c3bcc3521c81 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -501,6 +501,9 @@ static void ima_lsm_update_rules(void)
int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
void *lsm_data)
{
+ if (!ima_initialised)
+ return NOTIFY_DONE;
+
if (event != LSM_POLICY_CHANGE)
return NOTIFY_DONE;
diff --git a/security/lsm_init.c b/security/lsm_init.c
index 573e2a7250c4..4e5c59beb82a 100644
--- a/security/lsm_init.c
+++ b/security/lsm_init.c
@@ -547,13 +547,22 @@ device_initcall(security_initcall_device);
* security_initcall_late - Run the LSM late initcalls
*/
static int __init security_initcall_late(void)
+{
+ return lsm_initcall(late);
+}
+late_initcall(security_initcall_late);
+
+/**
+ * security_initcall_late_sync - Run the LSM late initcalls sync
+ */
+static int __init security_initcall_late_sync(void)
{
int rc;
- rc = lsm_initcall(late);
+ rc = lsm_initcall(late_sync);
lsm_pr_dbg("all enabled LSMs fully activated\n");
call_blocking_lsm_notifier(LSM_STARTED_ALL, NULL);
return rc;
}
-late_initcall(security_initcall_late);
+late_initcall_sync(security_initcall_late_sync);
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related
* [RFC PATCH v2 2/4] tpm: tpm_crb_ffa: revert defered_probed when tpm_crb_ffa is built-in
From: Yeoreum Yun @ 2026-04-22 16:24 UTC (permalink / raw)
To: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm
Cc: paul, jmorris, serge, zohar, roberto.sassu, dmitry.kasatkin,
eric.snowberg, jarkko, jgg, sudeep.holla, maz, oupton, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, will, noodles,
sebastianene, Yeoreum Yun
In-Reply-To: <20260422162449.1814615-1-yeoreum.yun@arm.com>
commit 746d9e9f62a6 ("tpm: tpm_crb_ffa: try to probe tpm_crb_ffa when it's build_in")
probe tpm_crb_ffa forcefully when it's built-in to integrate with IMA.
However, as IMA init function is changed to late_initcall_sync level.
So, this change isn't required anymore.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/char/tpm/tpm_crb_ffa.c | 18 +++---------------
1 file changed, 3 insertions(+), 15 deletions(-)
diff --git a/drivers/char/tpm/tpm_crb_ffa.c b/drivers/char/tpm/tpm_crb_ffa.c
index 99f1c1e5644b..025c4d4b17ca 100644
--- a/drivers/char/tpm/tpm_crb_ffa.c
+++ b/drivers/char/tpm/tpm_crb_ffa.c
@@ -177,23 +177,13 @@ static int tpm_crb_ffa_to_linux_errno(int errno)
*/
int tpm_crb_ffa_init(void)
{
- int ret = 0;
-
- if (!IS_MODULE(CONFIG_TCG_ARM_CRB_FFA)) {
- ret = ffa_register(&tpm_crb_ffa_driver);
- if (ret) {
- tpm_crb_ffa = ERR_PTR(-ENODEV);
- return ret;
- }
- }
-
if (!tpm_crb_ffa)
- ret = -ENOENT;
+ return -ENOENT;
if (IS_ERR_VALUE(tpm_crb_ffa))
- ret = -ENODEV;
+ return -ENODEV;
- return ret;
+ return 0;
}
EXPORT_SYMBOL_GPL(tpm_crb_ffa_init);
@@ -405,9 +395,7 @@ static struct ffa_driver tpm_crb_ffa_driver = {
.id_table = tpm_crb_ffa_device_id,
};
-#ifdef MODULE
module_ffa_driver(tpm_crb_ffa_driver);
-#endif
MODULE_AUTHOR("Arm");
MODULE_DESCRIPTION("TPM CRB FFA driver");
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related
* [RFC PATCH v2 3/4] firmware: arm_ffa: revert ffa_init() initcall level to device_initcall
From: Yeoreum Yun @ 2026-04-22 16:24 UTC (permalink / raw)
To: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm
Cc: paul, jmorris, serge, zohar, roberto.sassu, dmitry.kasatkin,
eric.snowberg, jarkko, jgg, sudeep.holla, maz, oupton, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, will, noodles,
sebastianene, Yeoreum Yun
In-Reply-To: <20260422162449.1814615-1-yeoreum.yun@arm.com>
commit 0e0546eabcd6 ("firmware: arm_ffa: Change initcall level of ffa_init() to rootfs_initcall")
changed the initcall level of ffa_init() to rootfs_initcall to address
an issue where IMA could not properly recognize the TPM device.
However, this introduces a problem: pKVM fails to handle any FF-A calls
because it cannot trap the FFA_VERSION call invoked by ffa_init().
Since the IMA init function level has been changed to late_initcall_sync,
there is no longer a need to keep ffa_init() at rootfs_initcall.
Revert it back to device_initcall.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
drivers/firmware/arm_ffa/driver.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index f2f94d4d533e..02c76ac1570b 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -2106,7 +2106,7 @@ static int __init ffa_init(void)
kfree(drv_info);
return ret;
}
-rootfs_initcall(ffa_init);
+device_initcall(ffa_init);
static void __exit ffa_exit(void)
{
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related
* [RFC PATCH v2 4/4] firmware: arm_ffa: check pkvm initailised when initailise ffa driver
From: Yeoreum Yun @ 2026-04-22 16:24 UTC (permalink / raw)
To: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm
Cc: paul, jmorris, serge, zohar, roberto.sassu, dmitry.kasatkin,
eric.snowberg, jarkko, jgg, sudeep.holla, maz, oupton, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, will, noodles,
sebastianene, Yeoreum Yun
In-Reply-To: <20260422162449.1814615-1-yeoreum.yun@arm.com>
When pKVM is enabled, the FF-A driver must be initialized after pKVM.
Otherwise, pKVM cannot negotiate the FF-A version or
obtain RX/TX buffer information, leading to failures in FF-A calls.
During FF-A driver initialization, check whether pKVM has been initialized.
If pKVM isn't initailised, register notifier and do initialisation
of FF-A driver when pKVM is initialized.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
---
arch/arm64/include/asm/virt.h | 11 ++++++++++
arch/arm64/kvm/arm.c | 21 ++++++++++++++++++
arch/arm64/kvm/pkvm.c | 2 ++
drivers/firmware/arm_ffa/common.h | 4 ++--
drivers/firmware/arm_ffa/driver.c | 36 ++++++++++++++++++++++++++++++-
drivers/firmware/arm_ffa/smccc.c | 2 +-
6 files changed, 72 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index b51ab6840f9c..ad038a3b8727 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -68,6 +68,8 @@
#include <asm/sysreg.h>
#include <asm/cpufeature.h>
+struct notifier_block;
+
/*
* __boot_cpu_mode records what mode CPUs were booted in.
* A correctly-implemented bootloader must start all CPUs in the same mode:
@@ -166,6 +168,15 @@ static inline bool is_hyp_nvhe(void)
return is_hyp_mode_available() && !is_kernel_in_hyp_mode();
}
+enum kvm_arm_event {
+ PKVM_INITIALISED,
+ KVM_ARM_EVENT_MAX,
+};
+
+extern int kvm_arm_event_notifier_call_chain(enum kvm_arm_event event, void *data);
+extern int kvm_arm_event_notifier_register(struct notifier_block *nb);
+extern int kvm_arm_event_notifier_unregister(struct notifier_block *nb);
+
#endif /* __ASSEMBLER__ */
#endif /* ! __ASM__VIRT_H */
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 410ffd41fd73..8da10049ab65 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -14,6 +14,7 @@
#include <linux/vmalloc.h>
#include <linux/fs.h>
#include <linux/mman.h>
+#include <linux/notifier.h>
#include <linux/sched.h>
#include <linux/kvm.h>
#include <linux/kvm_irqfd.h>
@@ -111,6 +112,8 @@ DECLARE_KVM_NVHE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);
DECLARE_KVM_NVHE_PER_CPU(struct kvm_cpu_context, kvm_hyp_ctxt);
+BLOCKING_NOTIFIER_HEAD(kvm_arm_event_notifier_head);
+
static bool vgic_present, kvm_arm_initialised;
static DEFINE_PER_CPU(unsigned char, kvm_hyp_initialized);
@@ -3064,4 +3067,22 @@ enum kvm_mode kvm_get_mode(void)
return kvm_mode;
}
+int kvm_arm_event_notifier_call_chain(enum kvm_arm_event event, void *data)
+{
+ return blocking_notifier_call_chain(&kvm_arm_event_notifier_head,
+ event, data);
+}
+
+int kvm_arm_event_notifier_register(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(&kvm_arm_event_notifier_head, nb);
+}
+EXPORT_SYMBOL_GPL(kvm_arm_event_notifier_register);
+
+int kvm_arm_event_notifier_unregister(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(&kvm_arm_event_notifier_head, nb);
+}
+EXPORT_SYMBOL_GPL(kvm_arm_event_notifier_unregister);
+
module_init(kvm_arm_init);
diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c
index d7a0f69a9982..e76562b0a45a 100644
--- a/arch/arm64/kvm/pkvm.c
+++ b/arch/arm64/kvm/pkvm.c
@@ -280,6 +280,8 @@ static int __init finalize_pkvm(void)
ret = pkvm_drop_host_privileges();
if (ret)
pr_err("Failed to finalize Hyp protection: %d\n", ret);
+ else
+ kvm_arm_event_notifier_call_chain(PKVM_INITIALISED, NULL);
return ret;
}
diff --git a/drivers/firmware/arm_ffa/common.h b/drivers/firmware/arm_ffa/common.h
index 9c6425a81d0d..5cdf4bd222c6 100644
--- a/drivers/firmware/arm_ffa/common.h
+++ b/drivers/firmware/arm_ffa/common.h
@@ -18,9 +18,9 @@ bool ffa_device_is_valid(struct ffa_device *ffa_dev);
void ffa_device_match_uuid(struct ffa_device *ffa_dev, const uuid_t *uuid);
#ifdef CONFIG_ARM_FFA_SMCCC
-int __init ffa_transport_init(ffa_fn **invoke_ffa_fn);
+int ffa_transport_init(ffa_fn **invoke_ffa_fn);
#else
-static inline int __init ffa_transport_init(ffa_fn **invoke_ffa_fn)
+static inline int ffa_transport_init(ffa_fn **invoke_ffa_fn)
{
return -EOPNOTSUPP;
}
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index 02c76ac1570b..67df053e65b8 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -35,6 +35,7 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/mutex.h>
+#include <linux/notifier.h>
#include <linux/of_irq.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
@@ -42,6 +43,8 @@
#include <linux/uuid.h>
#include <linux/xarray.h>
+#include <asm/virt.h>
+
#include "common.h"
#define FFA_DRIVER_VERSION FFA_VERSION_1_2
@@ -2029,7 +2032,7 @@ static void ffa_notifications_setup(void)
ffa_notifications_cleanup();
}
-static int __init ffa_init(void)
+static int __ffa_init(void)
{
int ret;
u32 buf_sz;
@@ -2105,11 +2108,42 @@ static int __init ffa_init(void)
free_drv_info:
kfree(drv_info);
return ret;
+
+}
+
+static int ffa_kvm_arm_event_handler(struct notifier_block *nb,
+ unsigned long event, void *unused)
+{
+ if (event == PKVM_INITIALISED)
+ __ffa_init();
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block ffa_kvm_arm_event_notifier = {
+ .notifier_call = ffa_kvm_arm_event_handler,
+};
+
+static int __init ffa_init(void)
+{
+ /*
+ * When pKVM is enabled, the FF-A driver must be initialized
+ * after pKVM initialization. Otherwise, pKVM cannot negotiate
+ * the FF-A version or obtain RX/TX buffer information,
+ * which leads to failures in FF-A calls.
+ */
+ if (IS_ENABLED(CONFIG_KVM) && is_protected_kvm_enabled() &&
+ !is_pkvm_initialized())
+ return kvm_arm_event_notifier_register(&ffa_kvm_arm_event_notifier);
+
+ return __ffa_init();
}
device_initcall(ffa_init);
static void __exit ffa_exit(void)
{
+ if (IS_ENABLED(CONFIG_KVM))
+ kvm_arm_event_notifier_unregister(&ffa_kvm_arm_event_notifier);
ffa_notifications_cleanup();
ffa_partitions_cleanup();
ffa_rxtx_unmap();
diff --git a/drivers/firmware/arm_ffa/smccc.c b/drivers/firmware/arm_ffa/smccc.c
index 4d85bfff0a4e..e6125dd9f58f 100644
--- a/drivers/firmware/arm_ffa/smccc.c
+++ b/drivers/firmware/arm_ffa/smccc.c
@@ -17,7 +17,7 @@ static void __arm_ffa_fn_hvc(ffa_value_t args, ffa_value_t *res)
arm_smccc_1_2_hvc(&args, res);
}
-int __init ffa_transport_init(ffa_fn **invoke_ffa_fn)
+int ffa_transport_init(ffa_fn **invoke_ffa_fn)
{
enum arm_smccc_conduit conduit;
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply related
* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Mimi Zohar @ 2026-04-22 17:20 UTC (permalink / raw)
To: Yeoreum Yun, linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm
Cc: paul, jmorris, serge, roberto.sassu, dmitry.kasatkin,
eric.snowberg, jarkko, jgg, sudeep.holla, maz, oupton, joey.gouly,
suzuki.poulose, yuzenghui, catalin.marinas, will, noodles,
sebastianene
In-Reply-To: <20260422162449.1814615-2-yeoreum.yun@arm.com>
On Wed, 2026-04-22 at 17:24 +0100, Yeoreum Yun wrote:
> To generate the boot_aggregate log in the IMA subsystem with TPM PCR values,
> the TPM driver must be built as built-in and
> must be probed before the IMA subsystem is initialized.
>
> However, when the TPM device operates over the FF-A protocol using
> the CRB interface, probing fails and returns -EPROBE_DEFER if
> the tpm_crb_ffa device — an FF-A device that provides the communication
> interface to the tpm_crb driver — has not yet been probed.
>
> To ensure the TPM device operating over the FF-A protocol with
> the CRB interface is probed before IMA initialization,
> the following conditions must be met:
>
> 1. The corresponding ffa_device must be registered,
> which is done via ffa_init().
>
> 2. The tpm_crb_driver must successfully probe this device via
> tpm_crb_ffa_init().
>
> 3. The tpm_crb driver using CRB over FF-A can then
> be probed successfully. (See crb_acpi_add() and
> tpm_crb_ffa_init() for reference.)
>
> Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
> all registered with device_initcall, which means crb_acpi_driver_init() may
> be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
>
> When this occurs, probing the TPM device is deferred.
> However, the deferred probe can happen after the IMA subsystem
> has already been initialized, since IMA initialization is performed
> during late_initcall, and deferred_probe_initcall() is performed
> at the same level.
>
> To resolve this, call ima_init() again at late_inicall_sync level
> so that let IMA not miss TPM PCR value when generating boot_aggregate
> log though TPM device presents in the system.
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
A lot of change for just detecting whether ima_init() is being called on
late_initcall or late_initcall_sync(), without any explanation for all the other
changes (e.g. ima_init_core).
Please just limit the change to just calling ima_init() twice.
Mimi
> ---
> include/linux/lsm_hooks.h | 2 +
> security/integrity/ima/ima.h | 4 +-
> security/integrity/ima/ima_init.c | 10 +++-
> security/integrity/ima/ima_main.c | 76 +++++++++++++++++++++++------
> security/integrity/ima/ima_policy.c | 3 ++
> security/lsm_init.c | 13 ++++-
> 6 files changed, 87 insertions(+), 21 deletions(-)
>
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index d48bf0ad26f4..88fe105b7f00 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -166,6 +166,7 @@ enum lsm_order {
> * @initcall_fs: LSM callback for fs_initcall setup, optional
> * @initcall_device: LSM callback for device_initcall() setup, optional
> * @initcall_late: LSM callback for late_initcall() setup, optional
> + * @initcall_late_sync: LSM callback for late_initcall_sync() setup, optional
> */
> struct lsm_info {
> const struct lsm_id *id;
> @@ -181,6 +182,7 @@ struct lsm_info {
> int (*initcall_fs)(void);
> int (*initcall_device)(void);
> int (*initcall_late)(void);
> + int (*initcall_late_sync)(void);
> };
>
> #define DEFINE_LSM(lsm) \
> diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> index 89ebe98ffc5e..75ee7ad184d0 100644
> --- a/security/integrity/ima/ima.h
> +++ b/security/integrity/ima/ima.h
> @@ -62,6 +62,8 @@ extern int ima_hash_algo_idx __ro_after_init;
> extern int ima_extra_slots __ro_after_init;
> extern struct ima_algo_desc *ima_algo_array __ro_after_init;
>
> +extern bool ima_initialised __ro_after_init;
> +
> extern int ima_appraise;
> extern struct tpm_chip *ima_tpm_chip;
> extern const char boot_aggregate_name[];
> @@ -257,7 +259,7 @@ static inline void ima_measure_kexec_event(const char *event_name) {}
> extern bool ima_canonical_fmt;
>
> /* Internal IMA function definitions */
> -int ima_init(void);
> +int ima_init(bool late);
> int ima_fs_init(void);
> int ima_add_template_entry(struct ima_template_entry *entry, int violation,
> const char *op, struct inode *inode,
> diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
> index a2f34f2d8ad7..c28c71090ad2 100644
> --- a/security/integrity/ima/ima_init.c
> +++ b/security/integrity/ima/ima_init.c
> @@ -115,13 +115,19 @@ void __init ima_load_x509(void)
> }
> #endif
>
> -int __init ima_init(void)
> +int __init ima_init(bool late)
> {
> int rc;
>
> ima_tpm_chip = tpm_default_chip();
> - if (!ima_tpm_chip)
> + if (!ima_tpm_chip) {
> + if (!late) {
> + pr_info("Defer initialisation to the late_initcall_sync stage.\n");
> + return -EPROBE_DEFER;
> + }
> +
> pr_info("No TPM chip found, activating TPM-bypass!\n");
> + }
>
> rc = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
> if (rc)
> diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> index 1d6229b156fb..ac444ee600e2 100644
> --- a/security/integrity/ima/ima_main.c
> +++ b/security/integrity/ima/ima_main.c
> @@ -38,6 +38,7 @@ int ima_appraise;
> #endif
>
> int __ro_after_init ima_hash_algo = HASH_ALGO_SHA1;
> +bool ima_initialised __ro_after_init = false;
> static int hash_setup_done;
> static int ima_disabled __ro_after_init;
>
> @@ -1237,6 +1238,35 @@ static int ima_kernel_module_request(char *kmod_name)
>
> #endif /* CONFIG_INTEGRITY_ASYMMETRIC_KEYS */
>
> +static int __init init_ima_core(bool late)
> +{
> + int err;
> +
> + if (ima_initialised)
> + return 0;
> +
> + err = ima_init(late);
> + if (err == -EPROBE_DEFER)
> + return 0;
> +
> + if (err && strcmp(hash_algo_name[ima_hash_algo],
> + CONFIG_IMA_DEFAULT_HASH) != 0) {
> + pr_info("Allocating %s failed, going to use default hash algorithm %s\n",
> + hash_algo_name[ima_hash_algo], CONFIG_IMA_DEFAULT_HASH);
> + hash_setup_done = 0;
> + hash_setup(CONFIG_IMA_DEFAULT_HASH);
> + err = ima_init(late);
> + }
> +
> + if (!err) {
> + ima_update_policy_flags();
> + ima_initialised = true;
> + } else
> + ima_disabled = 1;
> +
> + return err;
> +}
> +
> static int __init init_ima(void)
> {
> int error;
> @@ -1250,30 +1280,42 @@ static int __init init_ima(void)
> ima_appraise_parse_cmdline();
> ima_init_template_list();
> hash_setup(CONFIG_IMA_DEFAULT_HASH);
> - error = ima_init();
> -
> - if (error && strcmp(hash_algo_name[ima_hash_algo],
> - CONFIG_IMA_DEFAULT_HASH) != 0) {
> - pr_info("Allocating %s failed, going to use default hash algorithm %s\n",
> - hash_algo_name[ima_hash_algo], CONFIG_IMA_DEFAULT_HASH);
> - hash_setup_done = 0;
> - hash_setup(CONFIG_IMA_DEFAULT_HASH);
> - error = ima_init();
> - }
> -
> - if (error)
> - return error;
>
> error = register_blocking_lsm_notifier(&ima_lsm_policy_notifier);
> - if (error)
> + if (error) {
> pr_warn("Couldn't register LSM notifier, error %d\n", error);
> + goto disable_ima;
> + }
>
> - if (!error)
> - ima_update_policy_flags();
> + error = init_ima_core(false);
> + if (error) {
> + unregister_blocking_lsm_notifier(&ima_lsm_policy_notifier);
> + goto disable_ima;
> + }
> +
> + return 0;
>
> +disable_ima:
> + ima_disabled = 1;
> return error;
> }
>
> +static int __init late_init_ima(void)
> +{
> + int err;
> +
> + if (ima_disabled)
> + return 0;
> +
> + err = init_ima_core(true);
> + if (err) {
> + unregister_blocking_lsm_notifier(&ima_lsm_policy_notifier);
> + ima_disabled = 1;
> + }
> +
> + return err;
> +}
> +
> static struct security_hook_list ima_hooks[] __ro_after_init = {
> LSM_HOOK_INIT(bprm_check_security, ima_bprm_check),
> LSM_HOOK_INIT(bprm_creds_for_exec, ima_bprm_creds_for_exec),
> @@ -1321,4 +1363,6 @@ DEFINE_LSM(ima) = {
> .blobs = &ima_blob_sizes,
> /* Start IMA after the TPM is available */
> .initcall_late = init_ima,
> + /* Start IMA late in case of probing TPM is deferred. */
> + .initcall_late_sync = late_init_ima,
> };
> diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> index bf2d7ba4c14a..c3bcc3521c81 100644
> --- a/security/integrity/ima/ima_policy.c
> +++ b/security/integrity/ima/ima_policy.c
> @@ -501,6 +501,9 @@ static void ima_lsm_update_rules(void)
> int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
> void *lsm_data)
> {
> + if (!ima_initialised)
> + return NOTIFY_DONE;
> +
> if (event != LSM_POLICY_CHANGE)
> return NOTIFY_DONE;
>
> diff --git a/security/lsm_init.c b/security/lsm_init.c
> index 573e2a7250c4..4e5c59beb82a 100644
> --- a/security/lsm_init.c
> +++ b/security/lsm_init.c
> @@ -547,13 +547,22 @@ device_initcall(security_initcall_device);
> * security_initcall_late - Run the LSM late initcalls
> */
> static int __init security_initcall_late(void)
> +{
> + return lsm_initcall(late);
> +}
> +late_initcall(security_initcall_late);
> +
> +/**
> + * security_initcall_late_sync - Run the LSM late initcalls sync
> + */
> +static int __init security_initcall_late_sync(void)
> {
> int rc;
>
> - rc = lsm_initcall(late);
> + rc = lsm_initcall(late_sync);
> lsm_pr_dbg("all enabled LSMs fully activated\n");
> call_blocking_lsm_notifier(LSM_STARTED_ALL, NULL);
>
> return rc;
> }
> -late_initcall(security_initcall_late);
> +late_initcall_sync(security_initcall_late_sync);
> --
> LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
^ permalink raw reply
* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Yeoreum Yun @ 2026-04-22 18:46 UTC (permalink / raw)
To: Mimi Zohar
Cc: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm, paul, jmorris, serge, roberto.sassu,
dmitry.kasatkin, eric.snowberg, jarkko, jgg, sudeep.holla, maz,
oupton, joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
will, noodles, sebastianene
In-Reply-To: <6919248bdc85dac60277fa9d9c83d8bd258ca635.camel@linux.ibm.com>
Hi Mimi,
> On Wed, 2026-04-22 at 17:24 +0100, Yeoreum Yun wrote:
> > To generate the boot_aggregate log in the IMA subsystem with TPM PCR values,
> > the TPM driver must be built as built-in and
> > must be probed before the IMA subsystem is initialized.
> >
> > However, when the TPM device operates over the FF-A protocol using
> > the CRB interface, probing fails and returns -EPROBE_DEFER if
> > the tpm_crb_ffa device — an FF-A device that provides the communication
> > interface to the tpm_crb driver — has not yet been probed.
> >
> > To ensure the TPM device operating over the FF-A protocol with
> > the CRB interface is probed before IMA initialization,
> > the following conditions must be met:
> >
> > 1. The corresponding ffa_device must be registered,
> > which is done via ffa_init().
> >
> > 2. The tpm_crb_driver must successfully probe this device via
> > tpm_crb_ffa_init().
> >
> > 3. The tpm_crb driver using CRB over FF-A can then
> > be probed successfully. (See crb_acpi_add() and
> > tpm_crb_ffa_init() for reference.)
> >
> > Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
> > all registered with device_initcall, which means crb_acpi_driver_init() may
> > be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
> >
> > When this occurs, probing the TPM device is deferred.
> > However, the deferred probe can happen after the IMA subsystem
> > has already been initialized, since IMA initialization is performed
> > during late_initcall, and deferred_probe_initcall() is performed
> > at the same level.
> >
> > To resolve this, call ima_init() again at late_inicall_sync level
> > so that let IMA not miss TPM PCR value when generating boot_aggregate
> > log though TPM device presents in the system.
> >
> > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
>
> A lot of change for just detecting whether ima_init() is being called on
> late_initcall or late_initcall_sync(), without any explanation for all the other
> changes (e.g. ima_init_core).
>
> Please just limit the change to just calling ima_init() twice.
My concern is that ima_update_policy_flags() will be called
when ima_init() is deferred -- not initialised anything.
though functionally, it might be okay however,
I think ima_update_policy_flags() and notifier should work after ima_init()
works logically.
This change I think not much quite a lot. just wrapper ima_init() with
ima_init_core() with some error handling.
Am I missing something?
>
>
> > ---
> > include/linux/lsm_hooks.h | 2 +
> > security/integrity/ima/ima.h | 4 +-
> > security/integrity/ima/ima_init.c | 10 +++-
> > security/integrity/ima/ima_main.c | 76 +++++++++++++++++++++++------
> > security/integrity/ima/ima_policy.c | 3 ++
> > security/lsm_init.c | 13 ++++-
> > 6 files changed, 87 insertions(+), 21 deletions(-)
> >
> > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> > index d48bf0ad26f4..88fe105b7f00 100644
> > --- a/include/linux/lsm_hooks.h
> > +++ b/include/linux/lsm_hooks.h
> > @@ -166,6 +166,7 @@ enum lsm_order {
> > * @initcall_fs: LSM callback for fs_initcall setup, optional
> > * @initcall_device: LSM callback for device_initcall() setup, optional
> > * @initcall_late: LSM callback for late_initcall() setup, optional
> > + * @initcall_late_sync: LSM callback for late_initcall_sync() setup, optional
> > */
> > struct lsm_info {
> > const struct lsm_id *id;
> > @@ -181,6 +182,7 @@ struct lsm_info {
> > int (*initcall_fs)(void);
> > int (*initcall_device)(void);
> > int (*initcall_late)(void);
> > + int (*initcall_late_sync)(void);
> > };
> >
> > #define DEFINE_LSM(lsm) \
> > diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
> > index 89ebe98ffc5e..75ee7ad184d0 100644
> > --- a/security/integrity/ima/ima.h
> > +++ b/security/integrity/ima/ima.h
> > @@ -62,6 +62,8 @@ extern int ima_hash_algo_idx __ro_after_init;
> > extern int ima_extra_slots __ro_after_init;
> > extern struct ima_algo_desc *ima_algo_array __ro_after_init;
> >
> > +extern bool ima_initialised __ro_after_init;
> > +
> > extern int ima_appraise;
> > extern struct tpm_chip *ima_tpm_chip;
> > extern const char boot_aggregate_name[];
> > @@ -257,7 +259,7 @@ static inline void ima_measure_kexec_event(const char *event_name) {}
> > extern bool ima_canonical_fmt;
> >
> > /* Internal IMA function definitions */
> > -int ima_init(void);
> > +int ima_init(bool late);
> > int ima_fs_init(void);
> > int ima_add_template_entry(struct ima_template_entry *entry, int violation,
> > const char *op, struct inode *inode,
> > diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
> > index a2f34f2d8ad7..c28c71090ad2 100644
> > --- a/security/integrity/ima/ima_init.c
> > +++ b/security/integrity/ima/ima_init.c
> > @@ -115,13 +115,19 @@ void __init ima_load_x509(void)
> > }
> > #endif
> >
> > -int __init ima_init(void)
> > +int __init ima_init(bool late)
> > {
> > int rc;
> >
> > ima_tpm_chip = tpm_default_chip();
> > - if (!ima_tpm_chip)
> > + if (!ima_tpm_chip) {
> > + if (!late) {
> > + pr_info("Defer initialisation to the late_initcall_sync stage.\n");
> > + return -EPROBE_DEFER;
> > + }
> > +
> > pr_info("No TPM chip found, activating TPM-bypass!\n");
> > + }
> >
> > rc = integrity_init_keyring(INTEGRITY_KEYRING_IMA);
> > if (rc)
> > diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
> > index 1d6229b156fb..ac444ee600e2 100644
> > --- a/security/integrity/ima/ima_main.c
> > +++ b/security/integrity/ima/ima_main.c
> > @@ -38,6 +38,7 @@ int ima_appraise;
> > #endif
> >
> > int __ro_after_init ima_hash_algo = HASH_ALGO_SHA1;
> > +bool ima_initialised __ro_after_init = false;
> > static int hash_setup_done;
> > static int ima_disabled __ro_after_init;
> >
> > @@ -1237,6 +1238,35 @@ static int ima_kernel_module_request(char *kmod_name)
> >
> > #endif /* CONFIG_INTEGRITY_ASYMMETRIC_KEYS */
> >
> > +static int __init init_ima_core(bool late)
> > +{
> > + int err;
> > +
> > + if (ima_initialised)
> > + return 0;
> > +
> > + err = ima_init(late);
> > + if (err == -EPROBE_DEFER)
> > + return 0;
> > +
> > + if (err && strcmp(hash_algo_name[ima_hash_algo],
> > + CONFIG_IMA_DEFAULT_HASH) != 0) {
> > + pr_info("Allocating %s failed, going to use default hash algorithm %s\n",
> > + hash_algo_name[ima_hash_algo], CONFIG_IMA_DEFAULT_HASH);
> > + hash_setup_done = 0;
> > + hash_setup(CONFIG_IMA_DEFAULT_HASH);
> > + err = ima_init(late);
> > + }
> > +
> > + if (!err) {
> > + ima_update_policy_flags();
> > + ima_initialised = true;
> > + } else
> > + ima_disabled = 1;
> > +
> > + return err;
> > +}
> > +
> > static int __init init_ima(void)
> > {
> > int error;
> > @@ -1250,30 +1280,42 @@ static int __init init_ima(void)
> > ima_appraise_parse_cmdline();
> > ima_init_template_list();
> > hash_setup(CONFIG_IMA_DEFAULT_HASH);
> > - error = ima_init();
> > -
> > - if (error && strcmp(hash_algo_name[ima_hash_algo],
> > - CONFIG_IMA_DEFAULT_HASH) != 0) {
> > - pr_info("Allocating %s failed, going to use default hash algorithm %s\n",
> > - hash_algo_name[ima_hash_algo], CONFIG_IMA_DEFAULT_HASH);
> > - hash_setup_done = 0;
> > - hash_setup(CONFIG_IMA_DEFAULT_HASH);
> > - error = ima_init();
> > - }
> > -
> > - if (error)
> > - return error;
> >
> > error = register_blocking_lsm_notifier(&ima_lsm_policy_notifier);
> > - if (error)
> > + if (error) {
> > pr_warn("Couldn't register LSM notifier, error %d\n", error);
> > + goto disable_ima;
> > + }
> >
> > - if (!error)
> > - ima_update_policy_flags();
> > + error = init_ima_core(false);
> > + if (error) {
> > + unregister_blocking_lsm_notifier(&ima_lsm_policy_notifier);
> > + goto disable_ima;
> > + }
> > +
> > + return 0;
> >
> > +disable_ima:
> > + ima_disabled = 1;
> > return error;
> > }
> >
> > +static int __init late_init_ima(void)
> > +{
> > + int err;
> > +
> > + if (ima_disabled)
> > + return 0;
> > +
> > + err = init_ima_core(true);
> > + if (err) {
> > + unregister_blocking_lsm_notifier(&ima_lsm_policy_notifier);
> > + ima_disabled = 1;
> > + }
> > +
> > + return err;
> > +}
> > +
> > static struct security_hook_list ima_hooks[] __ro_after_init = {
> > LSM_HOOK_INIT(bprm_check_security, ima_bprm_check),
> > LSM_HOOK_INIT(bprm_creds_for_exec, ima_bprm_creds_for_exec),
> > @@ -1321,4 +1363,6 @@ DEFINE_LSM(ima) = {
> > .blobs = &ima_blob_sizes,
> > /* Start IMA after the TPM is available */
> > .initcall_late = init_ima,
> > + /* Start IMA late in case of probing TPM is deferred. */
> > + .initcall_late_sync = late_init_ima,
> > };
> > diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
> > index bf2d7ba4c14a..c3bcc3521c81 100644
> > --- a/security/integrity/ima/ima_policy.c
> > +++ b/security/integrity/ima/ima_policy.c
> > @@ -501,6 +501,9 @@ static void ima_lsm_update_rules(void)
> > int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
> > void *lsm_data)
> > {
> > + if (!ima_initialised)
> > + return NOTIFY_DONE;
> > +
> > if (event != LSM_POLICY_CHANGE)
> > return NOTIFY_DONE;
> >
> > diff --git a/security/lsm_init.c b/security/lsm_init.c
> > index 573e2a7250c4..4e5c59beb82a 100644
> > --- a/security/lsm_init.c
> > +++ b/security/lsm_init.c
> > @@ -547,13 +547,22 @@ device_initcall(security_initcall_device);
> > * security_initcall_late - Run the LSM late initcalls
> > */
> > static int __init security_initcall_late(void)
> > +{
> > + return lsm_initcall(late);
> > +}
> > +late_initcall(security_initcall_late);
> > +
> > +/**
> > + * security_initcall_late_sync - Run the LSM late initcalls sync
> > + */
> > +static int __init security_initcall_late_sync(void)
> > {
> > int rc;
> >
> > - rc = lsm_initcall(late);
> > + rc = lsm_initcall(late_sync);
> > lsm_pr_dbg("all enabled LSMs fully activated\n");
> > call_blocking_lsm_notifier(LSM_STARTED_ALL, NULL);
> >
> > return rc;
> > }
> > -late_initcall(security_initcall_late);
> > +late_initcall_sync(security_initcall_late_sync);
> > --
> > LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
--
Sincerely,
Yeoreum Yun
^ permalink raw reply
* Re: [PATCH RFC bpf-next 0/4] audit: Expose audit subsystem to BPF LSM programs via BPF kfuncs
From: Frederick Lawler @ 2026-04-22 18:50 UTC (permalink / raw)
To: Paul Moore
Cc: Alexei Starovoitov, Linus Torvalds, James Morris, Serge E. Hallyn,
Eric Paris, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Song Liu, Yonghong Song,
John Fastabend, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa,
Shuah Khan, Mickaël Salaün, Günther Noack, LKML,
LSM List, audit, bpf, open list:KERNEL SELFTEST FRAMEWORK,
kernel-team
In-Reply-To: <CAHC9VhT0poHt_9P407tr3ihfMGJYH0d9=PKxW0sk7gYF8fD5Lg@mail.gmail.com>
Hi Alexei & Paul,
Thanks for the comments. I did not mean for the talk announcement to
end in this state.
I understood the RFC was NACK'd, but I thought having a talk at LSS
could open up for some additional discussion around what can be done
with audit to make it more BPF friendly. I apologize.
My assumption is that the committee would've denied the talk if there
wasn't _some_ interest here. And still intend to give it unless
committee decides to revoke it, because there is always opportunity
to improve subsystems.
On Wed, Apr 22, 2026 at 10:33:27AM -0400, Paul Moore wrote:
> On Tue, Apr 21, 2026 at 7:08 PM Alexei Starovoitov
> > Every time somebody adds a kfunc it breaks safety, because
> > people don't read or don't understand Documentation/bpf/kfuncs.rst.
> > kfuncs are not export_symbol.
> > Object ownership model needs to be thought through.
> > Calling context needs to be analyzed and so on.
> > Just because something "works for me" it doesn't mean
> > that it's safe.
I interpreted this comment as more broadly applied to patch
submissions in general, and not this patch series itself (necessarily).
I do think that "... it breaks saftey ... kfuncs are not export_symbol"
is what the crux here is. I argue that that Documentation/bpf/kfuncs.rst
should be improved if this is a common trap that I and others fall in.
As I understood kfuncs, the point is to move away from BPF helpers so
that subsystems can have a export_symbol of sorts.
To quote:
BPF Kernel Functions or more commonly known as kfuncs are functions
in the Linux kernel which are exposed for use by BPF programs
Unlike normal BPF helpers, kfuncs do not have a stable interface
and can change from one kernel release to another.
...
As Paul mentioned, there are examples of the export_symbols use case, and
even one whose sole purpose is to crash the kernel: crash_kexec()[1]
And to be clear, I don't think that is a bad or uneeded patch. I just find it
interesting and unexpected that it was applied.
Maybe this series is the straw that breaks the camel's back?
>
> Unfortunately that isn't the review you provided Fred in this thread.
> There were no comments about object ownership, calling context,
> safety, etc., only a dismissive comment telling Fred to use something
> else for logging. If you want to provide proper feedback, something
> along the lines of Kumar's constructive review, I think Fred would
> welcome that.
>
Agreed. I can work with addressing calling context and object ownership
concerns. I thought I addressed these, but I'd like to know if there's
something I didn't consider.
Best,
Fred
[1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=133790596406ce2658f0864eb7eac64987c2b12f
^ permalink raw reply
* Re: [RFC PATCH v2 1/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM
From: Yeoreum Yun @ 2026-04-22 19:41 UTC (permalink / raw)
To: Mimi Zohar
Cc: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm, paul, jmorris, serge, roberto.sassu,
dmitry.kasatkin, eric.snowberg, jarkko, jgg, sudeep.holla, maz,
oupton, joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
will, noodles, sebastianene
In-Reply-To: <aekXaU52fzvNYaUF@e129823.arm.com>
> Hi Mimi,
>
> > On Wed, 2026-04-22 at 17:24 +0100, Yeoreum Yun wrote:
> > > To generate the boot_aggregate log in the IMA subsystem with TPM PCR values,
> > > the TPM driver must be built as built-in and
> > > must be probed before the IMA subsystem is initialized.
> > >
> > > However, when the TPM device operates over the FF-A protocol using
> > > the CRB interface, probing fails and returns -EPROBE_DEFER if
> > > the tpm_crb_ffa device — an FF-A device that provides the communication
> > > interface to the tpm_crb driver — has not yet been probed.
> > >
> > > To ensure the TPM device operating over the FF-A protocol with
> > > the CRB interface is probed before IMA initialization,
> > > the following conditions must be met:
> > >
> > > 1. The corresponding ffa_device must be registered,
> > > which is done via ffa_init().
> > >
> > > 2. The tpm_crb_driver must successfully probe this device via
> > > tpm_crb_ffa_init().
> > >
> > > 3. The tpm_crb driver using CRB over FF-A can then
> > > be probed successfully. (See crb_acpi_add() and
> > > tpm_crb_ffa_init() for reference.)
> > >
> > > Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
> > > all registered with device_initcall, which means crb_acpi_driver_init() may
> > > be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
> > >
> > > When this occurs, probing the TPM device is deferred.
> > > However, the deferred probe can happen after the IMA subsystem
> > > has already been initialized, since IMA initialization is performed
> > > during late_initcall, and deferred_probe_initcall() is performed
> > > at the same level.
> > >
> > > To resolve this, call ima_init() again at late_inicall_sync level
> > > so that let IMA not miss TPM PCR value when generating boot_aggregate
> > > log though TPM device presents in the system.
> > >
> > > Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
> >
> > A lot of change for just detecting whether ima_init() is being called on
> > late_initcall or late_initcall_sync(), without any explanation for all the other
> > changes (e.g. ima_init_core).
> >
> > Please just limit the change to just calling ima_init() twice.
>
> My concern is that ima_update_policy_flags() will be called
> when ima_init() is deferred -- not initialised anything.
> though functionally, it might be okay however,
> I think ima_update_policy_flags() and notifier should work after ima_init()
> works logically.
>
> This change I think not much quite a lot. just wrapper ima_init() with
> ima_init_core() with some error handling.
>
> Am I missing something?
Also, if we handle in ima_init() only, but it failed with other reason,
we shouldn't call again ima_init() in the late_initcall_sync.
To handle this, It wouldn't do in the ima_init() but we need to handle
it by caller of ima_init().
--
Sincerely,
Yeoreum Yun
^ permalink raw reply
* Re: [RFC PATCH v1 11/11] landlock: Add documentation for capability and namespace restrictions
From: Günther Noack @ 2026-04-22 20:38 UTC (permalink / raw)
To: Mickaël Salaün
Cc: Christian Brauner, Günther Noack, Paul Moore,
Serge E . Hallyn, Justin Suess, Lennart Poettering,
Mikhail Ivanov, Nicolas Bouchinet, Shervin Oloumi, Tingmao Wang,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module
In-Reply-To: <20260312100444.2609563-12-mic@digikod.net>
Hello!
On Thu, Mar 12, 2026 at 11:04:44AM +0100, Mickaël Salaün wrote:
> Document the two new Landlock permission categories in the userspace
> API guide, admin guide, and kernel security documentation.
>
> The userspace API guide adds sections on capability restriction
> (LANDLOCK_PERM_CAPABILITY_USE with LANDLOCK_RULE_CAPABILITY), namespace
> restriction (LANDLOCK_PERM_NAMESPACE_ENTER with LANDLOCK_RULE_NAMESPACE
> covering creation via unshare/clone and entry via setns), and the
> backward-compatible degradation pattern for ABI < 9. A table documents
> the per-namespace-type capability requirements for both creation and
> entry.
>
> The admin guide adds the new perm.namespace_enter and
> perm.capability_use audit blocker names with their object identification
> fields (namespace_type, namespace_inum, capability).
>
> The kernel security documentation adds a "Ruleset restriction models"
> section defining the three models (handled_access_*, handled_perm,
> scoped), their coverage and compatibility properties, and the criteria
> for choosing between them for future features. It also documents
> composability with user namespaces and adds kernel-doc references for
> the new capability and namespace headers.
>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Günther Noack <gnoack@google.com>
> Cc: Paul Moore <paul@paul-moore.com>
> Cc: Serge E. Hallyn <serge@hallyn.com>
> Signed-off-by: Mickaël Salaün <mic@digikod.net>
> ---
> Documentation/admin-guide/LSM/landlock.rst | 19 ++-
> Documentation/security/landlock.rst | 80 ++++++++++-
> Documentation/userspace-api/landlock.rst | 156 ++++++++++++++++++++-
> 3 files changed, 245 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/admin-guide/LSM/landlock.rst b/Documentation/admin-guide/LSM/landlock.rst
> index 9923874e2156..99c6a599ce9e 100644
> --- a/Documentation/admin-guide/LSM/landlock.rst
> +++ b/Documentation/admin-guide/LSM/landlock.rst
> @@ -6,7 +6,7 @@ Landlock: system-wide management
> ================================
>
> :Author: Mickaël Salaün
> -:Date: January 2026
> +:Date: March 2026
>
> Landlock can leverage the audit framework to log events.
>
> @@ -59,14 +59,25 @@ AUDIT_LANDLOCK_ACCESS
> - scope.abstract_unix_socket - Abstract UNIX socket connection denied
> - scope.signal - Signal sending denied
>
> + **perm.*** - Permission restrictions (ABI 9+):
> + - perm.namespace_enter - Namespace entry was denied (creation via
> + :manpage:`unshare(2)` / :manpage:`clone(2)` or joining via
> + :manpage:`setns(2)`);
> + ``namespace_type`` indicates the type (hex CLONE_NEW* bitmask),
> + ``namespace_inum`` identifies the target namespace for
> + :manpage:`setns(2)` operations
> + - perm.capability_use - Capability use was denied;
> + ``capability`` indicates the capability number
> +
> Multiple blockers can appear in a single event (comma-separated) when
> multiple access rights are missing. For example, creating a regular file
> in a directory that lacks both ``make_reg`` and ``refer`` rights would show
> ``blockers=fs.make_reg,fs.refer``.
>
> - The object identification fields (path, dev, ino for filesystem; opid,
> - ocomm for signals) depend on the type of access being blocked and provide
> - context about what resource was involved in the denial.
> + The object identification fields depend on the type of access being blocked:
> + ``path``, ``dev``, ``ino`` for filesystem; ``opid``, ``ocomm`` for signals;
> + ``namespace_type`` and ``namespace_inum`` for namespace operations;
> + ``capability`` for capability use.
>
>
> AUDIT_LANDLOCK_DOMAIN
> diff --git a/Documentation/security/landlock.rst b/Documentation/security/landlock.rst
> index 3e4d4d04cfae..cd3d640ca5c9 100644
> --- a/Documentation/security/landlock.rst
> +++ b/Documentation/security/landlock.rst
> @@ -7,7 +7,7 @@ Landlock LSM: kernel documentation
> ==================================
>
> :Author: Mickaël Salaün
> -:Date: September 2025
> +:Date: March 2026
>
> Landlock's goal is to create scoped access-control (i.e. sandboxing). To
> harden a whole system, this feature should be available to any process,
> @@ -89,6 +89,72 @@ this is required to keep access controls consistent over the whole system, and
> this avoids unattended bypasses through file descriptor passing (i.e. confused
> deputy attack).
>
> +Composability with user namespaces
> +----------------------------------
> +
> +Landlock domain-based scoping and the kernel's user namespace-based capability
> +scoping enforce isolation over independent hierarchies. Landlock checks domain
> +ancestry; the kernel's ``ns_capable()`` checks user namespace ancestry. These
> +hierarchies are orthogonal: Landlock enforcement is deterministic with respect
> +to its own configuration, regardless of namespace or capability state, and vice
> +versa. This orthogonality is a design invariant that must hold for all new
> +scoped features.
> +
> +Ruleset restriction models
> +--------------------------
I have to second Justin, it's a good idea to introduce this explanation.
> +
> +Landlock provides three restriction models, each with different coverage
> +and compatibility properties.
> +
> +Access rights (``handled_access_*``)
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Access rights control **enumerated operations on kernel objects**
> +identified by a rule key (a file hierarchy or a network port). Each
> +``handled_access_*`` field declares a set of access rights that the
> +ruleset restricts. Multiple access rights share a single rule type.
> +Operations for which no access right exists yet remain uncontrolled;
> +new rights are added incrementally across ABI versions.
> +
> +Permissions (``handled_perm``)
> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> +
> +Permissions control **broad operations enforced at single kernel
> +chokepoints**, achieving complete deny-by-default coverage. Each
> +``LANDLOCK_PERM_*`` flag maps to its own rule type. When a ruleset
> +handles a permission, all instances of that operation are denied unless
> +explicitly allowed by a rule. New kernel values (new ``CAP_*``
> +capabilities, new ``CLONE_NEW*`` namespace types) are automatically
> +denied without any Landlock update.
I find the terminology of "chokepoints" and "gateways" in this and the
header documentation a bit vague; you could argue that opening a file
for reading is also a chokepoint/gateway for using read() later on;
it's not immediately clear to me how that's delineated.
In my mind, the handled_* groups of access rights are usually defined
by the "namespace" of the objects they are protecting, more than
anything else: handled_access_fs: file paths, handled_access_net:
struct sockaddr (which we only expose as "port" for now).
To play the devil's advocate, a possible alternative would have been
to introduce:
handled_access_ns with values LANDLOCK_ACCESS_NS_FOO_ENTER,
LANDLOCK_ACCESS_NS_BAR_ENTER, etc. (and documenting somewhere that
these are guaranteed to stay in sync; a static assert is enough to
make sure they do).
handled_access_caps with values LANDLOCK_ACCESS_CAPS_USE_FOO,
LANDLOCK_ACCESS_CAPS_USE_BAR, etc., also guaranteed to stay in sync.
That way the blocked accesses would still be "operations", and we
would not need to have rules for them because the "object" being
protected are the processes within the Landlock domain, so to say.
Arguably, the LANDLOCK_ACCESS_FS_MAKE_* rights already follow a
similar pattern.
To be clear, I am myself only 50% convinced whether the API would be
better. The implementation would be easier (but that doesn't count
much in comparison).
> +Each permission flag names a single gateway operation whose control
> +transitively covers an open-ended set of downstream operations: for
> +example, exercising a capability enables privileged operations across
> +many subsystems; entering a namespace enables gaining capabilities in a
> +new context.
> +
> +Permission rules identify what to allow using constants defined by other
> +kernel subsystems (``CAP_*``, ``CLONE_NEW*``). Unknown values are
> +silently ignored because deny-by-default ensures they are denied anyway.
> +In contrast, unknown ``LANDLOCK_PERM_*`` flags in ``handled_perm`` are
> +rejected (``-EINVAL``), since Landlock owns that namespace.
OK I played through the compatibility scenarios which puzzled me in my
reply to the cover letter, for both namespaces and capabilities.
Namespaces are OK, so I'm just including that for completeness and for
comparison, but I think the capabilities might be tricky?
Case A: Namespaces
In the scenario where a caller restricts
LANDLOCK_PERM_NAMESPACE_ENTER, but then adds a rule to allow a
non-existent namespace number like 1<<63.
Landlock ABI v9:
* The rule is accepted and the unknown value for the namespace type
silently ignored
* It is not possible to enter the namespace because the namespace API
doesn't exist for it. (But that's appropriate.)
Landlock ABI v_future (the namespace type 1<<63 exists now):
* The rule continues to be accepted.
* When trying to exercise the namespace type, it works.
It seems that this scenario works fine. In the earlier version,
entering the namespace already doesn't work because the kernel doesn't
have support for it.
Case B: Capabilities
Whne new capabilities are introduced, I see that people have used the
pattern where these capabilities are split off from operations which
were previously controlled by CAP_SYS_ADMIN. An example is commit
a17b53c4a4b5 ("bpf, capability: Introduce CAP_BPF"), which states:
Split BPF operations that are allowed under CAP_SYS_ADMIN into
combination of CAP_BPF, CAP_PERFMON, CAP_NET_ADMIN. For backward
compatibility include them in CAP_SYS_ADMIN as well.
(The same pattern was also used in the introduction of
CAP_CHECKPOINT_RESTORE and CAP_PERFMON. CAP_AUDIT_READ is older and
did it differently.)
Let's say there is a frobnicate() syscall guarded by CAP_SYS_ADMIN. A
future kernel introduces CAP_FOO and then checks for frobnicate() that
either one of CAP_FOO or CAP_SYS_ADMIN are present.
A caller creates a ruleset restricting capability use with Landlock,
and adds a rule to allow CAP_FOO but not CAP_SYS_ADMIN (e.g.,
^CAP_SYS_ADMIN)
Landlock ABI v9: (CAP_FOO doesn't exist)
* The rule for CAP_FOO is accepted and the unknown value for the
capability silently ignored.
* The call to frobnicate() fails because the use of the capability is
forbidden
Landlock ABI v10: (CAP_FOO starts to exist)
* The rule continues to be accepted
* The call to frobnicate() **succeeds now**, because the new kernel guards
the operation by either one of those capabilities.
So... for capabilities, it seems to be slightly incompatible if users
allow capabilities with a rule which are not known yet? The reason
for that is the way how capabilities "fork off" from CAP_SYS_ADMIN.
I mean, I can see that it's a pretty fringe scenario if users pass
capabilities that don't exist yet, but it *is* strictly speaking an
incompatibiliy. Should we check the range of the passed capabilities?
Am I overlooking any downsides to this if we force users to stay
between 0 and CAP_LAST_CAP?
> +
> +Scopes (``scoped``)
> +~~~~~~~~~~~~~~~~~~~~
> +
> +Scopes restrict **cross-domain interactions** categorically, without
> +rules. Setting a scope flag (e.g. ``LANDLOCK_SCOPE_SIGNAL``) denies the
> +operation to targets outside the Landlock domain or its children. Like
> +permissions, scopes provide complete coverage of the controlled
> +operation.
> +
> +When adding new Landlock features, new operations on existing rule types
> +extend the corresponding ``handled_access_*`` field (e.g. a new
> +filesystem operation extends ``handled_access_fs``). A new object
> +category with multiple fine-grained operations would use a new
> +``handled_access_*`` field. New rule types that control a single
> +chokepoint operation use ``handled_perm``.
> +
> Tests
> =====
>
> @@ -110,6 +176,18 @@ Filesystem
> .. kernel-doc:: security/landlock/fs.h
> :identifiers:
>
> +Namespace
> +---------
> +
> +.. kernel-doc:: security/landlock/ns.h
> + :identifiers:
> +
> +Capability
> +----------
> +
> +.. kernel-doc:: security/landlock/cap.h
> + :identifiers:
> +
> Process credential
> ------------------
>
> diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst
> index 13134bccdd39..238d30a18162 100644
> --- a/Documentation/userspace-api/landlock.rst
> +++ b/Documentation/userspace-api/landlock.rst
> @@ -8,7 +8,7 @@ Landlock: unprivileged access control
> =====================================
>
> :Author: Mickaël Salaün
> -:Date: January 2026
> +:Date: March 2026
>
> The goal of Landlock is to enable restriction of ambient rights (e.g. global
> filesystem or network access) for a set of processes. Because Landlock
> @@ -33,7 +33,7 @@ A Landlock rule describes an action on an object which the process intends to
> perform. A set of rules is aggregated in a ruleset, which can then restrict
> the thread enforcing it, and its future children.
>
> -The two existing types of rules are:
> +The existing types of rules are:
>
> Filesystem rules
> For these rules, the object is a file hierarchy,
> @@ -44,6 +44,14 @@ Network rules (since ABI v4)
> For these rules, the object is a TCP port,
> and the related actions are defined with `network access rights`.
>
> +Capability rules (since ABI v9)
> + For these rules, the object is a set of Linux capabilities,
> + and the related actions are defined with `permission flags`.
> +
> +Namespace rules (since ABI v9)
> + For these rules, the object is a set of namespace types,
> + and the related actions are defined with `permission flags`.
> +
> Defining and enforcing a security policy
> ----------------------------------------
>
> @@ -84,6 +92,9 @@ to be explicit about the denied-by-default access rights.
> .scoped =
> LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
> LANDLOCK_SCOPE_SIGNAL,
> + .handled_perm =
> + LANDLOCK_PERM_CAPABILITY_USE |
> + LANDLOCK_PERM_NAMESPACE_ENTER,
> };
>
> Because we may not know which kernel version an application will be executed
> @@ -127,6 +138,12 @@ version, and only use the available subset of access rights:
> /* Removes LANDLOCK_SCOPE_* for ABI < 6 */
> ruleset_attr.scoped &= ~(LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
> LANDLOCK_SCOPE_SIGNAL);
> + __attribute__((fallthrough));
> + case 6:
> + case 7:
> + case 8:
> + /* Removes permission support for ABI < 9 */
> + ruleset_attr.handled_perm = 0;
> }
>
> This enables the creation of an inclusive ruleset that will contain our rules.
> @@ -191,6 +208,42 @@ number for a specific action: HTTPS connections.
> err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
> &net_port, 0);
>
> +For capability access-control, we can add rules that allow specific
> +capabilities. For instance, to allow ``CAP_SYS_CHROOT`` (so the sandboxed
> +process can call :manpage:`chroot(2)` inside a user namespace):
> +
> +.. code-block:: c
> +
> + struct landlock_capability_attr cap_attr = {
> + .allowed_perm = LANDLOCK_PERM_CAPABILITY_USE,
> + .capabilities = (1ULL << CAP_SYS_CHROOT),
> + };
> +
> + err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY,
> + &cap_attr, 0);
> +
> +For namespace access-control, we can add rules that allow entering specific
> +namespace types (creating them via :manpage:`unshare(2)` / :manpage:`clone(2)`
> +or joining them via :manpage:`setns(2)`). For instance, to allow creating user
> +namespaces (which grants all capabilities inside the new namespace):
> +
> +.. code-block:: c
> +
> + struct landlock_namespace_attr ns_attr = {
> + .allowed_perm = LANDLOCK_PERM_NAMESPACE_ENTER,
> + .namespace_types = CLONE_NEWUSER,
> + };
> +
> + err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE,
> + &ns_attr, 0);
> +
> +Together, these two rules allow an unprivileged process to create a user
> +namespace and call :manpage:`chroot(2)` inside it, while denying all other
> +capabilities and namespace types. User namespace creation is the one operation
> +that does not require ``CAP_SYS_ADMIN``, so no capability rule is needed for it.
> +See `Capability and namespace restrictions`_ for details on capability
> +requirements.
> +
> When passing a non-zero ``flags`` argument to ``landlock_restrict_self()``, a
> similar backwards compatibility check is needed for the restrict flags
> (see sys_landlock_restrict_self() documentation for available flags):
> @@ -354,10 +407,87 @@ The operations which can be scoped are:
> A :manpage:`sendto(2)` on a socket which was previously connected will not
> be restricted. This works for both datagram and stream sockets.
>
> -IPC scoping does not support exceptions via :manpage:`landlock_add_rule(2)`.
> +Scoping does not support exceptions via :manpage:`landlock_add_rule(2)`.
> If an operation is scoped within a domain, no rules can be added to allow access
> to resources or processes outside of the scope.
>
> +Capability and namespace restrictions
> +-------------------------------------
> +
> +See Documentation/security/landlock.rst for the design rationale behind
> +the permission model (``handled_perm``) and how it differs from access
> +rights (``handled_access_*``) and scopes (``scoped``).
> +When a process creates a user namespace, the kernel grants all capabilities
> +within that namespace. While these capabilities cannot directly bypass Landlock
> +restrictions (Landlock enforces access controls independently of capability
> +checks), they open kernel code paths that are normally unreachable to
> +unprivileged users and may contain exploitable bugs.
> +
> +Landlock provides two complementary permissions to address this.
> +``LANDLOCK_PERM_CAPABILITY_USE`` restricts which capabilities a process can use,
> +even when it holds them. ``LANDLOCK_PERM_NAMESPACE_ENTER`` restricts which
> +namespace types a process can create (via :manpage:`unshare(2)` or
> +:manpage:`clone(2)`) or join (via :manpage:`setns(2)`). After creating a user
> +namespace, the granted capabilities are scoped to namespaces owned by that user
> +namespace or its descendants; to exercise a capability such as
> +``CAP_NET_ADMIN``, the process must create a namespace of the corresponding type
> +(e.g., a network namespace). Configuring both permissions together provides
> +full coverage: ``LANDLOCK_PERM_CAPABILITY_USE`` restricts which capabilities are
> +available, while ``LANDLOCK_PERM_NAMESPACE_ENTER`` restricts the namespaces in
> +which they can be used.
> +
> +When a Landlock domain handles ``LANDLOCK_PERM_CAPABILITY_USE``, all Linux
> +:manpage:`capabilities(7)` are denied by default unless a rule explicitly allows
> +them. This is purely restrictive: Landlock can only deny capabilities that the
> +traditional capability mechanism would have allowed, never grant additional ones.
> +Rules are added with ``LANDLOCK_RULE_CAPABILITY`` using a
> +&struct landlock_capability_attr. Each rule specifies a set of ``CAP_*`` values
> +(as a bitmask) to allow. Capabilities above ``CAP_LAST_CAP`` are silently
> +accepted but have no effect since the kernel never checks them; this means new
> +capabilities introduced by future kernels are automatically denied.
(See example above.)
> +
> +When a Landlock domain handles ``LANDLOCK_PERM_NAMESPACE_ENTER``, namespace
> +creation and entry are denied by default unless a rule explicitly allows them.
> +Rules are added with ``LANDLOCK_RULE_NAMESPACE`` using a
> +&struct landlock_namespace_attr. Each rule specifies a set of ``CLONE_NEW*``
> +flags to allow.
> +
> +In practice, unprivileged processes first create a user namespace (which requires
> +no capability and grants all capabilities within it), then use those capabilities
> +to create other namespace types. All non-user namespace types require
> +``CAP_SYS_ADMIN`` for both creation and :manpage:`setns(2)` entry; mount
> +namespace entry additionally requires ``CAP_SYS_CHROOT``. For
> +:manpage:`setns(2)`, capabilities are checked relative to the target namespace,
> +so a process in an ancestor user namespace naturally satisfies them; this
> +includes joining user namespaces, which requires ``CAP_SYS_ADMIN``. When
> +``LANDLOCK_PERM_CAPABILITY_USE`` is also handled, each of these capabilities
> +must be explicitly allowed by a rule.
> +
> +When combining ``CLONE_NEWUSER`` with other ``CLONE_NEW*`` flags in a single
> +:manpage:`unshare(2)` call, the ``CAP_SYS_ADMIN`` check targets the newly
> +created user namespace, which is handled by ``LANDLOCK_PERM_NAMESPACE_ENTER``
> +independently from ``LANDLOCK_PERM_CAPABILITY_USE``. Performing the user
> +namespace creation and the additional namespace creation in two separate
> +:manpage:`unshare(2)` calls requires a rule allowing ``CAP_SYS_ADMIN`` if the
> +domain also handles ``LANDLOCK_PERM_CAPABILITY_USE``.
> +
> +More generally, Landlock domains and user namespaces form independent
> +hierarchies: Landlock domains restrict what actions are allowed (each stacked
> +layer narrows the permitted set), while user namespaces restrict where
> +capabilities take effect (only within the process's own namespace and its
> +descendants). Landlock access controls are fully determined by the domain
> +configuration, regardless of the process's position in the user namespace
> +hierarchy. When creating child user namespaces, it is recommended to also
> +create a dedicated Landlock domain with restrictions relevant to each namespace
> +context.
> +
> +Note that ``LANDLOCK_PERM_CAPABILITY_USE`` restricts the *use* of capabilities,
> +not their presence in the process's credential. Capability sets can change
> +after a domain is enforced through user namespace entry, :manpage:`execve(2)` of
> +binaries with file capabilities, or :manpage:`capset(2)`. In all cases,
> +:manpage:`capget(2)` will report the credential's capability sets, but any
> +denied capability will fail with ``EPERM`` when exercised.
> +
> Truncating files
> ----------------
>
> @@ -515,7 +645,7 @@ Access rights
> -------------
>
> .. kernel-doc:: include/uapi/linux/landlock.h
> - :identifiers: fs_access net_access scope
> + :identifiers: fs_access net_access scope perm
>
> Creating a new ruleset
> ----------------------
> @@ -534,7 +664,8 @@ Extending a ruleset
>
> .. kernel-doc:: include/uapi/linux/landlock.h
> :identifiers: landlock_rule_type landlock_path_beneath_attr
> - landlock_net_port_attr
> + landlock_net_port_attr landlock_capability_attr
> + landlock_namespace_attr
>
> Enforcing a ruleset
> -------------------
> @@ -685,6 +816,21 @@ enforce Landlock rulesets across all threads of the calling process
> using the ``LANDLOCK_RESTRICT_SELF_TSYNC`` flag passed to
> sys_landlock_restrict_self().
>
> +Capability restriction (ABI < 9)
> +--------------------------------
> +
> +Starting with the Landlock ABI version 9, it is possible to restrict
> +:manpage:`capabilities(7)` with the new ``LANDLOCK_PERM_CAPABILITY_USE``
> +permission flag and ``LANDLOCK_RULE_CAPABILITY`` rule type.
> +
> +Namespace restriction (ABI < 9)
> +-------------------------------
> +
> +Starting with the Landlock ABI version 9, it is possible to restrict
> +namespace creation (:manpage:`unshare(2)`, :manpage:`clone(2)`) and entry
> +(:manpage:`setns(2)`) with the new ``LANDLOCK_PERM_NAMESPACE_ENTER`` permission
> +flag and ``LANDLOCK_RULE_NAMESPACE`` rule type.
> +
> .. _kernel_support:
>
> Kernel support
> --
> 2.53.0
>
^ permalink raw reply
* Re: [RFC PATCH v1 00/11] Landlock: Namespace and capability control
From: Günther Noack @ 2026-04-22 21:16 UTC (permalink / raw)
To: Mickaël Salaün
Cc: Christian Brauner, Günther Noack, Paul Moore,
Serge E . Hallyn, Justin Suess, Lennart Poettering,
Mikhail Ivanov, Nicolas Bouchinet, Shervin Oloumi, Tingmao Wang,
kernel-team, linux-fsdevel, linux-kernel, linux-security-module
In-Reply-To: <20260421.aen9Pheishah@digikod.net>
On Tue, Apr 21, 2026 at 10:24:00AM +0200, Mickaël Salaün wrote:
> On Mon, Apr 20, 2026 at 05:06:32PM +0200, Günther Noack wrote:
> > Hello!
> >
> > On Thu, Mar 12, 2026 at 11:04:33AM +0100, Mickaël Salaün wrote:
> > > Namespaces are a fundamental building block for containers and
> > > application sandboxes, but user namespace creation significantly widens
> > > the kernel attack surface. CVE-2022-0185 (filesystem mount parsing),
> > > CVE-2022-25636 and CVE-2023-32233 (netfilter), and CVE-2022-0492 (cgroup
> > > v1 release_agent) all demonstrate vulnerabilities exploitable only
> > > through capabilities gained via user namespaces. Some distributions
> > > block user namespace creation entirely, but this removes a useful
> > > isolation primitive. Fine-grained control allows trusted programs to
> > > use namespaces while preventing unnecessary exposure for programs that
> > > do not need them.
> > >
> > > Existing mechanisms (user.max_*_namespaces sysctls, userns_create LSM
> > > hook, PR_SET_NO_NEW_PRIVS, and capset) each address part of this threat
> > > but none provides per-process, fine-grained control over both namespace
> > > types and capabilities. Container runtimes resort to seccomp-based
> > > clone/unshare filtering, but seccomp cannot dereference clone3's flag
> > > structure, forcing runtimes to block clone3 entirely.
> > >
> > > Landlock's composable layer model enables several patterns: a user
> > > session manager can restrict namespace types and capabilities broadly
> > > while allowing trusted programs to create the namespaces they need, and
> > > each deeper layer can further restrict the allowed set. Container
> > > runtimes can similarly deny namespace creation inside managed
> > > containers.
> >
> > I assume we are talking about an unrestricted systemd user session
> > manager, which would not itself be restricted? (If the entire user
> > session were running under Landlock, users couldn't change their
> > passwords with "passwd" any more, because of the no_new_privs
> > requirement.)
>
> systemd can be use to create such session, as other init systems.
> If no_new_privs is set, commands such as passwd would indeed not work,
> but:
> 1. The process applying the Landlock restrictions (e.g. creating the
> user session) doesn't need to set no_new_privs if it has
> CAP_SYS_ADMIN in the current user namespace.
> 2. SUID programs can (and should probably) be replaced with proper
> client/server interfaces (i.e. for the client to not be privileged),
> see DBus services (e.g. Account) or homectl for instance.
I also think services are a better approach than the suid bit, but
that's to my knowledge not the state of affairs yet (until Lennart
makes it happen, hint hint ;-)).
> > > This series adds two new permission categories to Landlock:
> > >
> > > - LANDLOCK_PERM_NAMESPACE_ENTER: Restricts which namespace types a
> > > sandboxed process can acquire: both creation (unshare/clone) and entry
> > > (setns). User namespace creation has no capability check in the
> > > kernel, so this is the only enforcement mechanism for that entry
> > > point.
> > >
> > > - LANDLOCK_PERM_CAPABILITY_USE: Restricts which Linux capabilities a
> > > sandboxed process can use, regardless of how they were obtained
> > > (including through user namespace creation).
> >
> > Given that you already went through multiple iterations here, I fully
>
> It's the first public one, but it's well advanced.
>
> > expect that I am overlooking something here, but based on the
> > explanation, it's not clear to me why the capability control is needed
> > in addition to the namespace control, to reduce the kernel attack
> > surface.
> >
> > In my understanding the "attack surface" problem with user namespaces
> > is that they allow unprivileged processes to gain CAP_SYS_ADMIN within
> > that namespace, which unlocks access to code paths which were
> > traditionally reserved for the (top level) root user.
>
> This capability and others.
>
> >
> > But then, to prevent that from happening, it seems that restricting
> > access to user namespace creation would be sufficient?
>
> It would be sufficient to limit the kernel attack surface, but it would
> make all the related features unusable. As explained in this cover
> letter, there are already several ways to block everything, but this
> doesn't help for a lot of use cases and this Landlock feature proposes a
> new fine-grained and unprivileged way to properly restrict some
> capabilities.
>
> >
> > (Also, in some cases, I suspect it might be possible to break
> > assumptions that more privileged processes make about filesystem
> > layout if the user can change the mount layout. But that is not an
> > issue with Landlock, as we forbid changes to mounts and also require
> > no_new_privs.)
> >
> >
> > > Both use new handled_perm and LANDLOCK_RULE_* constants following the
> > > existing allow-list model. The UAPI uses raw CAP_* and CLONE_NEW*
> > > values directly; unknown values are silently accepted for forward
> > > compatibility (the allow-list denies them by default). The Landlock ABI
> > > version is bumped from 8 to 9.
> >
> > Compatibility question:
> >
> > For both permission categories, when they are "handled" in the
> > ruleset, they default to denying *all* types of namespaces, and *all*
> > types of capabilities.
> >
> > This is different to the handled_access_* rights, where we are
> > requiring users to explicitly list all restricted rights as "handled",
> > because the full list of available operations might be a moving
> > target.
> >
> > Why is this not a problem for capabilities and for namespaces? Both
> > the list of capabilities and the list of namespaces has been expanded
> > in the past. What happens if a new capability or namespace is
> > invented? If these are evolved, is that backwards compatible for the
> > existing users of these Landlock permission categories?
>
> This question is answered is the documentation (and the commit
> messages), and that's the main difference between handled_access_* and
> handled_perm. In a nutshell, the permission rules uses non-Landlock
> bits that naturally evolve without any Landlock-specific changes.
I think the deny-by-default is fine given that these namespaces and
capabilities do not exist yet. It is the case where users add a rule
and we silently ignore unknown bits in the bitfield, which I think
introduces a small problem. I responded to the documentation commit
with what I believe is a counterexample for the capabilities case.
(Let's discuss it on the documentation patch in the context of the
examples.)
> > > The handled_perm infrastructure is designed to be reusable by future
> > > permission categories. The last patch documents the design rationale
> > > for the permission model and the criteria for choosing between
> > > handled_access_*, handled_perm, and scoped. A patch series to add
> > > socket creation control is under review [2]; it could benefit from the
> > > same permission model to achieve complete deny-by-default coverage of
> > > socket creation.
>
> See here ^
>
> > >
> > > This series builds on Christian Brauner's namespace LSM blob RFC [1],
> > > included as patch 1.
> > >
> > > Christian, could you please review patch 3? It adds a FOR_EACH_NS_TYPE
> > > X-macro to ns_common_types.h and derives CLONE_NS_ALL, replacing inline
> > > CLONE_NEW* flag enumerations in nsproxy.c and fork.c.
> > >
> > > Paul, could you please review patch 2? It adds LSM_AUDIT_DATA_NS, a new
> > > audit record type that logs namespace_type and inum for
> > > namespace-related LSM denials.
> > >
> > > All four example vulnerabilities follow the same pattern: an
> > > unprivileged user creates a user namespace to obtain capabilities, then
> > > creates a second namespace to exercise them against vulnerable code.
> > > LANDLOCK_PERM_NAMESPACE_ENTER prevents this by denying the user
> > > namespace (eliminating the capability grant) or the specific namespace
> > > type needed to exercise it. LANDLOCK_PERM_CAPABILITY_USE independently
> > > prevents it by denying the required capability.
> >
> > Here, it is also not clear to me why LANDLOCK_PERM_CAPABILITY_USE is
> > needed in addition to LANDLOCK_PERM_NAMESPACE_ENTER.
>
> This is also explained in the documentation.
> > Looking at capabilities(7), my understanding is that capabilities can
> > only be acquired through:
> >
> > (1) user namespaces (prevented with LANDLOCK_PERM_NAMESPACE_ENTER)
> > (2) execve (setuid or individual capabilities, prevented using
> > PR_SET_NO_NEW_PRIVS)
> >
> > ...so if a process were to start out with no such capabilities,
> > wouldn't that be enough to prevent it from gaining more? Am I
> > overlooking another way through which these can be acquired?
> >
> > The Landlock capability support adds a "filter" for the use of
> > capabilities, but my understanding of the capability system was that
> > it already *is* that filter. As long as we prevent the acquisition of
> > new capabilities, shouldn't that be sufficient?
>
> In a nutshell, capabilities applies to namespaces (and their type), so
> it makes sense to be able to control them together, see the chroot
> example. Please take a look at the documentation.
I had a hard time puzzling it together in the documentation, but the
chroot example helped.
So, if I am understanding correctly, the idea is that you need it in
order to create a new user namespace, but the restrict the use of
capabilities within that user namespace (not only CAP_SYS_ADMIN, but
also more individual ones). Sounds reasonable.
I can also see that in order to do that without the Landlock
capability support, the first process within the new namespace would
immediately need to drop capabilities, and that may be outside of the
control of the person defining the Landlock policy..?
–Günther
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox