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