* [PATCH v2][next] bpf: Avoid thousands of -Wflex-array-members-not-at-end warnings
@ 2026-03-30 22:38 Gustavo A. R. Silva
2026-03-31 11:07 ` Mykyta Yatsenko
2026-04-06 2:44 ` Alexei Starovoitov
0 siblings, 2 replies; 6+ messages in thread
From: Gustavo A. R. Silva @ 2026-03-30 22:38 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
Yonghong Song, KP Singh, Stanislav Fomichev, Hao Luo, Jiri Olsa
Cc: bpf, linux-kernel, Gustavo A. R. Silva, linux-hardening,
Kees Cook
Apparently, struct bpf_empty_prog_array exists entirely to populate a
single element of "items" in a global variable. "null_prog" is only
used during the initializer.
None of this is needed; globals will be correctly sized with an array
initializer of a flexible-array member.
So, remove struct bpf_empty_prog_array and adjust the rest of the code,
accordingly.
With these changes, fix the following warnings:
7659 ./include/linux/bpf.h:2369:31: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
---
Changes in v2:
- Remove struct bpf_empty_prog_array. (Kees)
v1:
-Link: https://lore.kernel.org/linux-hardening/aaZr2A1UPJq33127@kspp/
include/linux/bpf-cgroup.h | 2 +-
include/linux/bpf.h | 7 +------
kernel/bpf/core.c | 12 +++++++-----
3 files changed, 9 insertions(+), 12 deletions(-)
diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
index 2f535331f926..b2e79c2b41d5 100644
--- a/include/linux/bpf-cgroup.h
+++ b/include/linux/bpf-cgroup.h
@@ -184,7 +184,7 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
struct bpf_prog_array *array;
array = rcu_access_pointer(cgrp->bpf.effective[type]);
- return array != &bpf_empty_prog_array.hdr;
+ return array != &bpf_empty_prog_array;
}
/* Wrappers for __cgroup_bpf_run_filter_skb() guarded by cgroup_bpf_enabled. */
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 05b34a6355b0..4f5b9e85a20c 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -2365,18 +2365,13 @@ struct bpf_prog_array {
struct bpf_prog_array_item items[];
};
-struct bpf_empty_prog_array {
- struct bpf_prog_array hdr;
- struct bpf_prog *null_prog;
-};
-
/* to avoid allocating empty bpf_prog_array for cgroups that
* don't have bpf program attached use one global 'bpf_empty_prog_array'
* It will not be modified the caller of bpf_prog_array_alloc()
* (since caller requested prog_cnt == 0)
* that pointer should be 'freed' by bpf_prog_array_free()
*/
-extern struct bpf_empty_prog_array bpf_empty_prog_array;
+extern struct bpf_prog_array bpf_empty_prog_array;
struct bpf_prog_array *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags);
void bpf_prog_array_free(struct bpf_prog_array *progs);
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 67eb12b637a5..ca39d2e690b9 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -2613,8 +2613,10 @@ static struct bpf_prog_dummy {
},
};
-struct bpf_empty_prog_array bpf_empty_prog_array = {
- .null_prog = NULL,
+struct bpf_prog_array bpf_empty_prog_array = {
+ .items = {
+ { .prog = NULL },
+ },
};
EXPORT_SYMBOL(bpf_empty_prog_array);
@@ -2625,14 +2627,14 @@ struct bpf_prog_array *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags)
if (prog_cnt)
p = kzalloc_flex(*p, items, prog_cnt + 1, flags);
else
- p = &bpf_empty_prog_array.hdr;
+ p = &bpf_empty_prog_array;
return p;
}
void bpf_prog_array_free(struct bpf_prog_array *progs)
{
- if (!progs || progs == &bpf_empty_prog_array.hdr)
+ if (!progs || progs == &bpf_empty_prog_array)
return;
kfree_rcu(progs, rcu);
}
@@ -2653,7 +2655,7 @@ static void __bpf_prog_array_free_sleepable_cb(struct rcu_head *rcu)
void bpf_prog_array_free_sleepable(struct bpf_prog_array *progs)
{
- if (!progs || progs == &bpf_empty_prog_array.hdr)
+ if (!progs || progs == &bpf_empty_prog_array)
return;
call_rcu_tasks_trace(&progs->rcu, __bpf_prog_array_free_sleepable_cb);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2][next] bpf: Avoid thousands of -Wflex-array-members-not-at-end warnings
2026-03-30 22:38 [PATCH v2][next] bpf: Avoid thousands of -Wflex-array-members-not-at-end warnings Gustavo A. R. Silva
@ 2026-03-31 11:07 ` Mykyta Yatsenko
2026-04-06 2:44 ` Alexei Starovoitov
1 sibling, 0 replies; 6+ messages in thread
From: Mykyta Yatsenko @ 2026-03-31 11:07 UTC (permalink / raw)
To: Gustavo A. R. Silva, Alexei Starovoitov, Daniel Borkmann,
John Fastabend, Andrii Nakryiko, Martin KaFai Lau,
Eduard Zingerman, Song Liu, Yonghong Song, KP Singh,
Stanislav Fomichev, Hao Luo, Jiri Olsa
Cc: bpf, linux-kernel, linux-hardening, Kees Cook
On 3/30/26 11:38 PM, Gustavo A. R. Silva wrote:
> Apparently, struct bpf_empty_prog_array exists entirely to populate a
> single element of "items" in a global variable. "null_prog" is only
> used during the initializer.
>
> None of this is needed; globals will be correctly sized with an array
> initializer of a flexible-array member.
>
> So, remove struct bpf_empty_prog_array and adjust the rest of the code,
> accordingly.
>
> With these changes, fix the following warnings:
>
> 7659 ./include/linux/bpf.h:2369:31: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
>
> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> ---
Great cleanup! It was quite confusing how we used null_prog to fill the
fist element of the flexible array. I wonder why was it done like that.
Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
> Changes in v2:
> - Remove struct bpf_empty_prog_array. (Kees)
>
> v1:
> -Link: https://lore.kernel.org/linux-hardening/aaZr2A1UPJq33127@kspp/
>
> include/linux/bpf-cgroup.h | 2 +-
> include/linux/bpf.h | 7 +------
> kernel/bpf/core.c | 12 +++++++-----
> 3 files changed, 9 insertions(+), 12 deletions(-)
>
> diff --git a/include/linux/bpf-cgroup.h b/include/linux/bpf-cgroup.h
> index 2f535331f926..b2e79c2b41d5 100644
> --- a/include/linux/bpf-cgroup.h
> +++ b/include/linux/bpf-cgroup.h
> @@ -184,7 +184,7 @@ static inline bool cgroup_bpf_sock_enabled(struct sock *sk,
> struct bpf_prog_array *array;
>
> array = rcu_access_pointer(cgrp->bpf.effective[type]);
> - return array != &bpf_empty_prog_array.hdr;
> + return array != &bpf_empty_prog_array;
> }
>
> /* Wrappers for __cgroup_bpf_run_filter_skb() guarded by cgroup_bpf_enabled. */
> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 05b34a6355b0..4f5b9e85a20c 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -2365,18 +2365,13 @@ struct bpf_prog_array {
> struct bpf_prog_array_item items[];
> };
>
> -struct bpf_empty_prog_array {
> - struct bpf_prog_array hdr;
> - struct bpf_prog *null_prog;
> -};
> -
> /* to avoid allocating empty bpf_prog_array for cgroups that
> * don't have bpf program attached use one global 'bpf_empty_prog_array'
> * It will not be modified the caller of bpf_prog_array_alloc()
> * (since caller requested prog_cnt == 0)
> * that pointer should be 'freed' by bpf_prog_array_free()
> */
> -extern struct bpf_empty_prog_array bpf_empty_prog_array;
> +extern struct bpf_prog_array bpf_empty_prog_array;
>
> struct bpf_prog_array *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags);
> void bpf_prog_array_free(struct bpf_prog_array *progs);
> diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
> index 67eb12b637a5..ca39d2e690b9 100644
> --- a/kernel/bpf/core.c
> +++ b/kernel/bpf/core.c
> @@ -2613,8 +2613,10 @@ static struct bpf_prog_dummy {
> },
> };
>
> -struct bpf_empty_prog_array bpf_empty_prog_array = {
> - .null_prog = NULL,
> +struct bpf_prog_array bpf_empty_prog_array = {
> + .items = {
> + { .prog = NULL },
> + },
> };
> EXPORT_SYMBOL(bpf_empty_prog_array);
>
> @@ -2625,14 +2627,14 @@ struct bpf_prog_array *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags)
> if (prog_cnt)
> p = kzalloc_flex(*p, items, prog_cnt + 1, flags);
> else
> - p = &bpf_empty_prog_array.hdr;
> + p = &bpf_empty_prog_array;
>
> return p;
> }
>
> void bpf_prog_array_free(struct bpf_prog_array *progs)
> {
> - if (!progs || progs == &bpf_empty_prog_array.hdr)
> + if (!progs || progs == &bpf_empty_prog_array)
> return;
> kfree_rcu(progs, rcu);
> }
> @@ -2653,7 +2655,7 @@ static void __bpf_prog_array_free_sleepable_cb(struct rcu_head *rcu)
>
> void bpf_prog_array_free_sleepable(struct bpf_prog_array *progs)
> {
> - if (!progs || progs == &bpf_empty_prog_array.hdr)
> + if (!progs || progs == &bpf_empty_prog_array)
> return;
> call_rcu_tasks_trace(&progs->rcu, __bpf_prog_array_free_sleepable_cb);
> }
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2][next] bpf: Avoid thousands of -Wflex-array-members-not-at-end warnings
2026-03-30 22:38 [PATCH v2][next] bpf: Avoid thousands of -Wflex-array-members-not-at-end warnings Gustavo A. R. Silva
2026-03-31 11:07 ` Mykyta Yatsenko
@ 2026-04-06 2:44 ` Alexei Starovoitov
2026-04-06 3:27 ` Kees Cook
1 sibling, 1 reply; 6+ messages in thread
From: Alexei Starovoitov @ 2026-04-06 2:44 UTC (permalink / raw)
To: Gustavo A. R. Silva, Kees Cook
Cc: Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, bpf, LKML,
linux-hardening
On Mon, Mar 30, 2026 at 3:39 PM Gustavo A. R. Silva
<gustavoars@kernel.org> wrote:
>
> Apparently, struct bpf_empty_prog_array exists entirely to populate a
> single element of "items" in a global variable. "null_prog" is only
> used during the initializer.
>
> None of this is needed; globals will be correctly sized with an array
> initializer of a flexible-array member.
>
> So, remove struct bpf_empty_prog_array and adjust the rest of the code,
> accordingly.
>
> With these changes, fix the following warnings:
>
> 7659 ./include/linux/bpf.h:2369:31: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
>
> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> ---
> Changes in v2:
> - Remove struct bpf_empty_prog_array. (Kees)
Kees,
It really bothers me that you ask people to clean up
warnings for the sake of removing warnings.
This has to stop.
This patch adds a ticking time bomb.
See bpf_prog_run_array_cg() and think why it's an exploit
waiting to happen.
Fixing -Wflex-array-member-not-at-end warnings make the kernel more secure...
It's the opposite!
Such crusade against warnings introduces subtle bugs.
Look, this patch was Acked. bpf CI is green.
No failing tests and I was about to apply it,
since it looked correct on the first glance,
but something felt wrong...
'null_prog' was there for a reason.
I so hate this "hardening" cleanups that introduce bugs.
pw-bot: cr
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2][next] bpf: Avoid thousands of -Wflex-array-members-not-at-end warnings
2026-04-06 2:44 ` Alexei Starovoitov
@ 2026-04-06 3:27 ` Kees Cook
2026-04-06 23:24 ` Alexei Starovoitov
0 siblings, 1 reply; 6+ messages in thread
From: Kees Cook @ 2026-04-06 3:27 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Gustavo A. R. Silva, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, bpf, LKML, linux-hardening
On Sun, Apr 05, 2026 at 07:44:51PM -0700, Alexei Starovoitov wrote:
> On Mon, Mar 30, 2026 at 3:39 PM Gustavo A. R. Silva
> <gustavoars@kernel.org> wrote:
> >
> > Apparently, struct bpf_empty_prog_array exists entirely to populate a
> > single element of "items" in a global variable. "null_prog" is only
> > used during the initializer.
> >
> > None of this is needed; globals will be correctly sized with an array
> > initializer of a flexible-array member.
> >
> > So, remove struct bpf_empty_prog_array and adjust the rest of the code,
> > accordingly.
> >
> > With these changes, fix the following warnings:
> >
> > 7659 ./include/linux/bpf.h:2369:31: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
> >
> > Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> > ---
> > Changes in v2:
> > - Remove struct bpf_empty_prog_array. (Kees)
>
> Kees,
>
> It really bothers me that you ask people to clean up
> warnings for the sake of removing warnings.
It's not for the sake of warnings; this is to remove the ambiguously
sized objects (i.e. structs that the compiler cannot reason about the
size of).
--
Kees Cook
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2][next] bpf: Avoid thousands of -Wflex-array-members-not-at-end warnings
2026-04-06 3:27 ` Kees Cook
@ 2026-04-06 23:24 ` Alexei Starovoitov
2026-04-07 0:22 ` Gustavo A. R. Silva
0 siblings, 1 reply; 6+ messages in thread
From: Alexei Starovoitov @ 2026-04-06 23:24 UTC (permalink / raw)
To: Kees Cook
Cc: Gustavo A. R. Silva, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, bpf, LKML, linux-hardening
On Sun, Apr 5, 2026 at 8:27 PM Kees Cook <kees@kernel.org> wrote:
>
> On Sun, Apr 05, 2026 at 07:44:51PM -0700, Alexei Starovoitov wrote:
> > On Mon, Mar 30, 2026 at 3:39 PM Gustavo A. R. Silva
> > <gustavoars@kernel.org> wrote:
> > >
> > > Apparently, struct bpf_empty_prog_array exists entirely to populate a
> > > single element of "items" in a global variable. "null_prog" is only
> > > used during the initializer.
> > >
> > > None of this is needed; globals will be correctly sized with an array
> > > initializer of a flexible-array member.
> > >
> > > So, remove struct bpf_empty_prog_array and adjust the rest of the code,
> > > accordingly.
> > >
> > > With these changes, fix the following warnings:
> > >
> > > 7659 ./include/linux/bpf.h:2369:31: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
> > >
> > > Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
> > > ---
> > > Changes in v2:
> > > - Remove struct bpf_empty_prog_array. (Kees)
> >
> > Kees,
> >
> > It really bothers me that you ask people to clean up
> > warnings for the sake of removing warnings.
>
> It's not for the sake of warnings; this is to remove the ambiguously
> sized objects (i.e. structs that the compiler cannot reason about the
> size of).
I read through the AI debug logs. What steps it took to reason that
the fix is correct, and it convinced me that I'm wrong.
Applied.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2][next] bpf: Avoid thousands of -Wflex-array-members-not-at-end warnings
2026-04-06 23:24 ` Alexei Starovoitov
@ 2026-04-07 0:22 ` Gustavo A. R. Silva
0 siblings, 0 replies; 6+ messages in thread
From: Gustavo A. R. Silva @ 2026-04-07 0:22 UTC (permalink / raw)
To: Alexei Starovoitov, Kees Cook
Cc: Gustavo A. R. Silva, Daniel Borkmann, Andrii Nakryiko,
Eduard Zingerman, bpf, LKML, linux-hardening
On 4/6/26 17:24, Alexei Starovoitov wrote:
> On Sun, Apr 5, 2026 at 8:27 PM Kees Cook <kees@kernel.org> wrote:
>>
>> On Sun, Apr 05, 2026 at 07:44:51PM -0700, Alexei Starovoitov wrote:
>>> On Mon, Mar 30, 2026 at 3:39 PM Gustavo A. R. Silva
>>> <gustavoars@kernel.org> wrote:
>>>>
>>>> Apparently, struct bpf_empty_prog_array exists entirely to populate a
>>>> single element of "items" in a global variable. "null_prog" is only
>>>> used during the initializer.
>>>>
>>>> None of this is needed; globals will be correctly sized with an array
>>>> initializer of a flexible-array member.
>>>>
>>>> So, remove struct bpf_empty_prog_array and adjust the rest of the code,
>>>> accordingly.
>>>>
>>>> With these changes, fix the following warnings:
>>>>
>>>> 7659 ./include/linux/bpf.h:2369:31: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
>>>>
>>>> Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
>>>> ---
>>>> Changes in v2:
>>>> - Remove struct bpf_empty_prog_array. (Kees)
>>>
>>> Kees,
>>>
>>> It really bothers me that you ask people to clean up
>>> warnings for the sake of removing warnings.
>>
>> It's not for the sake of warnings; this is to remove the ambiguously
>> sized objects (i.e. structs that the compiler cannot reason about the
>> size of).
>
> I read through the AI debug logs. What steps it took to reason that
> the fix is correct, and it convinced me that I'm wrong.
What prompted you to think this was a "ticking time bomb"?
> Applied.
Thanks
-Gustavo
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-04-07 0:23 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-30 22:38 [PATCH v2][next] bpf: Avoid thousands of -Wflex-array-members-not-at-end warnings Gustavo A. R. Silva
2026-03-31 11:07 ` Mykyta Yatsenko
2026-04-06 2:44 ` Alexei Starovoitov
2026-04-06 3:27 ` Kees Cook
2026-04-06 23:24 ` Alexei Starovoitov
2026-04-07 0:22 ` Gustavo A. R. Silva
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.