Re: [PATCH v3 1/2] bpf: render CGROUP_LSM_NUM configurable as a KConfig

Paul Houssel <[email protected]> Thu, 7 May 2026 18:39:53 +0200
Newsgroups dev.linux.lists.sashiko,org.kernel.vger.bpf
Message-ID <CA+aJb_1vFaSvBjsZbi_EYhGfiefCruaEaLqgagX6HAGfLFxqGw@mail.gmail.com>
Ok, I agree I'll set the minimum value to 1 as I don't see a
motivation to would want to restrict per cgroup attachments if BPF LSM
is already allowed if CONFIG_BPF_LSM is set. I would like to have your
thoughts on the upper bound. 300 is currently higher than the actual
number of total LSM interfaces and would be considerable memory
overhead. With CONFIG_CGROUP_LSM_NUM=10, cgroup_bpf has 1024 bytes
since MAX_CGROUP_BPF_ATTACH_TYPE=38.

```
$ pahole cgroup_bpf
struct cgroup_bpf {
    struct bpf_prog_array *    effective[38];        /*     0   304 */
    /* --- cacheline 4 boundary (256 bytes) was 48 bytes ago --- */
    struct hlist_head          progs[38];            /*   304   304 */
    /* --- cacheline 9 boundary (576 bytes) was 32 bytes ago --- */
    u8                         flags[38];            /*   608    38 */

    /* XXX 2 bytes hole, try to pack */

    /* --- cacheline 10 boundary (640 bytes) was 8 bytes ago --- */
    u64                        revisions[38];        /*   648   304 */
    /* --- cacheline 14 boundary (896 bytes) was 56 bytes ago --- */
    struct list_head           storages;             /*   952    16 */
    /* --- cacheline 15 boundary (960 bytes) was 8 bytes ago --- */
    struct bpf_prog_array *    inactive;             /*   968     8 */
    struct percpu_ref          refcnt;               /*   976    16 */
    struct work_struct         release_work;         /*   992    32 */

    /* size: 1024, cachelines: 16, members: 8 */
    /* sum members: 1022, holes: 1, sum holes: 2 */
};
```

While with CONFIG_CGROUP_LSM_NUM=50, it has 2024 bytes, indeed adding
25 bytes per increment to CONFIG_CGROUP_LSM_NUM (8 + 8 + 8 + 1 per
slot for effective, progs, revisions, and flags):

```
$ pahole cgroup_bpf
struct cgroup_bpf {
    struct bpf_prog_array *    effective[78];        /*     0   624 */
    /* --- cacheline 9 boundary (576 bytes) was 48 bytes ago --- */
    struct hlist_head          progs[78];            /*   624   624 */
    /* --- cacheline 19 boundary (1216 bytes) was 32 bytes ago --- */
    u8                         flags[78];            /*  1248    78 */

    /* XXX 2 bytes hole, try to pack */

    /* --- cacheline 20 boundary (1280 bytes) was 48 bytes ago --- */
    u64                        revisions[78];        /*  1328   624 */
    /* --- cacheline 30 boundary (1920 bytes) was 32 bytes ago --- */
    struct list_head           storages;             /*  1952    16 */
    struct bpf_prog_array *    inactive;             /*  1968     8 */
    struct percpu_ref          refcnt;               /*  1976    16 */
    /* --- cacheline 31 boundary (1984 bytes) was 8 bytes ago --- */
    struct work_struct         release_work;         /*  1992    32 */

    /* size: 2024, cachelines: 32, members: 8 */
    /* sum members: 2022, holes: 1, sum holes: 2 */
    /* last cacheline: 40 bytes */
};
```

Above a certain threshold the memory overhead is too high indeed,
causing a crash on my VM. Probably caused by the raised stack concern,
exceeding CONFIG_FRAME_WARN=2048. I therefore propose capping at 50 to
be below FRAME_WARN. In practice eBPF-based tools may exceed this
limit of 10 but I don't see use-case requiring the attachment of all
LSM hooks. For example, Aqua Security's Tracee uses 24 LSM hooks[1],
and the recently announced MetArmor requires at least 14 LSM hooks if
they choose to trace the following events with LSM programs: execve,
bind, connect, accept, sendmsg, recvmsg, namespace creation, open,
kernel module loading, bpf, ptrace (covered by 2 LSM interfaces),
mount, and pivot_root (see slide 8 in [2]).
I would therefore propose to set the maximum value to 50 or 100 (where
cgroup_bpf is 2024 bytes long), what do you think Paul C?

[1] https://aquasecurity.github.io/tracee/latest/docs/events/
[2] https://lpc.events/event/19/contributions/2172/attachments/1845/3945/LPC%20
conference%20-%20Carl%20v2.pdf




On Wed, 6 May 2026 at 23:08, <[email protected]> wrote:
>
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [High] Increasing CONFIG_CGROUP_LSM_NUM to its maximum value (300) causes an excessive stack allocation in cgroup_bpf_inherit(), which will trigger a FRAME_WARN build failure and risks stack overflow.
> --
>
> commit 33800a93ec2833bc433c78926307347450251cdb
> Author: Paul Houssel <[email protected]>
>
> bpf: render CGROUP_LSM_NUM configurable as a KConfig
>
> This commit makes the maximum number of concurrently attachable per-cgroup
> LSM hooks configurable at build time via the new CONFIG_CGROUP_LSM_NUM
> option. It allows the value to be tuned from 0 to 300, replacing the
> previous hardcoded limit of 10.
>
> > diff --git a/include/linux/bpf-cgroup-defs.h b/include/linux/bpf-cgroup-defs.h
> > index c9e6b26abab6d..9ab5ca3dbaba3 100644
> > --- a/include/linux/bpf-cgroup-defs.h
> > +++ b/include/linux/bpf-cgroup-defs.h
>
> [ ... ]
>
> >  #ifdef CONFIG_BPF_LSM
> >  /* Maximum number of concurrently attachable per-cgroup LSM hooks. */
> > -#define CGROUP_LSM_NUM 10
> > +#define CGROUP_LSM_NUM CONFIG_CGROUP_LSM_NUM
> >  #else
> >  #define CGROUP_LSM_NUM 0
> >  #endif
>
> > diff --git a/kernel/bpf/Kconfig b/kernel/bpf/Kconfig
> > index eb3de35734f09..050af0b72651d 100644
> > --- a/kernel/bpf/Kconfig
> > +++ b/kernel/bpf/Kconfig
>
> [ ... ]
>
> > +config CGROUP_LSM_NUM
> > +     int "Maximum number of per-cgroup LSM hooks"
> > +     depends on BPF_LSM
> > +     depends on CGROUP_BPF
> > +     range 0 300
>
> If this is configured to the maximum value of 300, could this cause a
> regression by overflowing the kernel stack in cgroup_bpf_inherit()?
>
> In include/linux/bpf-cgroup-defs.h, MAX_CGROUP_BPF_ATTACH_TYPE scales
> dynamically based on CGROUP_LSM_NUM. At 300, MAX_CGROUP_BPF_ATTACH_TYPE
> grows to 328 (28 base hooks + 300).
>
> In kernel/bpf/cgroup.c, cgroup_bpf_inherit() computes NR as
> ARRAY_SIZE(cgrp->bpf.effective) and declares a local stack array:
>
> kernel/bpf/cgroup.c:cgroup_bpf_inherit() {
>         ...
>         #define NR ARRAY_SIZE(cgrp->bpf.effective)
>         struct bpf_prog_array *arrays[NR] = {};
>         ...
> }
>
> On 64-bit architectures, this array of pointers would consume 2624 bytes
> (328 * 8) on the stack. Does this exceed the standard CONFIG_FRAME_WARN
> limits and risk build failures or runtime stack overflows?
>
> --
> Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=1