All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.