linux/tools/include/uapi/linux
Kees Cook d9a429fec7 bpf: Replace bpf_lpm_trie_key 0-length array with flexible array
[ Upstream commit 896880ff30 ]

Replace deprecated 0-length array in struct bpf_lpm_trie_key with
flexible array. Found with GCC 13:

../kernel/bpf/lpm_trie.c:207:51: warning: array subscript i is outside array bounds of 'const __u8[0]' {aka 'const unsigned char[]'} [-Warray-bounds=]
  207 |                                        *(__be16 *)&key->data[i]);
      |                                                   ^~~~~~~~~~~~~
../include/uapi/linux/swab.h:102:54: note: in definition of macro '__swab16'
  102 | #define __swab16(x) (__u16)__builtin_bswap16((__u16)(x))
      |                                                      ^
../include/linux/byteorder/generic.h:97:21: note: in expansion of macro '__be16_to_cpu'
   97 | #define be16_to_cpu __be16_to_cpu
      |                     ^~~~~~~~~~~~~
../kernel/bpf/lpm_trie.c:206:28: note: in expansion of macro 'be16_to_cpu'
  206 |                 u16 diff = be16_to_cpu(*(__be16 *)&node->data[i]
^
      |                            ^~~~~~~~~~~
In file included from ../include/linux/bpf.h:7:
../include/uapi/linux/bpf.h:82:17: note: while referencing 'data'
   82 |         __u8    data[0];        /* Arbitrary size */
      |                 ^~~~

And found at run-time under CONFIG_FORTIFY_SOURCE:

  UBSAN: array-index-out-of-bounds in kernel/bpf/lpm_trie.c:218:49
  index 0 is out of range for type '__u8 [*]'

Changing struct bpf_lpm_trie_key is difficult since has been used by
userspace. For example, in Cilium:

	struct egress_gw_policy_key {
	        struct bpf_lpm_trie_key lpm_key;
	        __u32 saddr;
	        __u32 daddr;
	};

While direct references to the "data" member haven't been found, there
are static initializers what include the final member. For example,
the "{}" here:

        struct egress_gw_policy_key in_key = {
                .lpm_key = { 32 + 24, {} },
                .saddr   = CLIENT_IP,
                .daddr   = EXTERNAL_SVC_IP & 0Xffffff,
        };

To avoid the build time and run time warnings seen with a 0-sized
trailing array for struct bpf_lpm_trie_key, introduce a new struct
that correctly uses a flexible array for the trailing bytes,
struct bpf_lpm_trie_key_u8. As part of this, include the "header"
portion (which is just the "prefixlen" member), so it can be used
by anything building a bpf_lpr_trie_key that has trailing members that
aren't a u8 flexible array (like the self-test[1]), which is named
struct bpf_lpm_trie_key_hdr.

Unfortunately, C++ refuses to parse the __struct_group() helper, so
it is not possible to define struct bpf_lpm_trie_key_hdr directly in
struct bpf_lpm_trie_key_u8, so we must open-code the union directly.

Adjust the kernel code to use struct bpf_lpm_trie_key_u8 through-out,
and for the selftest to use struct bpf_lpm_trie_key_hdr. Add a comment
to the UAPI header directing folks to the two new options.

Reported-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Closes: https://paste.debian.net/hidden/ca500597/
Link: https://lore.kernel.org/all/202206281009.4332AA33@keescook/ [1]
Link: https://lore.kernel.org/bpf/20240222155612.it.533-kees@kernel.org
Stable-dep-of: 59f2f84117 ("bpf: Avoid kfree_rcu() under lock in bpf_lpm_trie.")
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2024-08-29 17:30:22 +02:00
..
tc_act headers: Remove some left-over license text 2022-09-27 07:48:01 -07:00
bpf.h bpf: Replace bpf_lpm_trie_key 0-length array with flexible array 2024-08-29 17:30:22 +02:00
bpf_common.h bpf: Sync kernel ABI header with tooling header for bpf_common.h 2018-02-09 00:24:38 +01:00
bpf_perf_event.h tools, headers: Sync struct bpf_perf_event_data 2021-01-26 00:15:03 +01:00
btf.h bpf: Add btf enum64 support 2022-06-07 10:20:42 -07:00
const.h tools headers UAPI: Sync linux/const.h with the kernel headers 2020-12-18 17:32:28 -03:00
erspan.h tools, include: Grab a copy of linux/erspan.h 2018-04-30 17:56:24 +02:00
ethtool.h tools: include: Add ethtool_drvinfo definition to UAPI header 2021-08-24 14:48:40 -07:00
fadvise.h tools headers uapi: Grab a copy of fadvise.h 2018-12-18 16:17:40 -03:00
fcntl.h tools headers API: Update faccessat2 affected files 2020-06-09 12:40:03 -03:00
filter.h tools: bpf: Use local copy of headers including uapi/linux/filter.h 2020-07-21 10:50:35 +01:00
fs.h treewide: uapi: Replace zero-length arrays with flexible-array members 2022-06-28 21:26:05 +02:00
fscrypt.h tools headers UAPI: Sync linux/fscrypt.h with the kernel sources 2022-08-19 15:30:33 -03:00
hw_breakpoint.h tools/headers: Synchronize kernel ABI headers 2017-11-04 09:27:46 +01:00
if_link.h Bonding: add per-port priority for failover re-selection 2022-06-24 11:27:59 +01:00
if_tun.h treewide: uapi: Replace zero-length arrays with flexible-array members 2022-06-28 21:26:05 +02:00
if_xdp.h xsk: Add new statistics 2020-07-13 15:32:56 -07:00
in.h tools headers UAPI: Sync the linux/in.h with the kernel sources 2023-06-05 09:26:22 +02:00
kcmp.h tools headers: Synchronize kernel ABI headers wrt SPDX tags 2017-11-28 14:29:20 -03:00
kvm.h tools: include: sync include/api/linux/kvm.h 2022-10-22 07:54:19 -04:00
mman.h tools UAPI: Update copy of linux/mman.h from the kernel sources 2020-11-03 08:36:51 -03:00
mount.h tools include UAPI: Update linux/mount.h copy 2021-09-10 18:15:22 -03:00
netlink.h net: netlink: rename NETLINK_DUMP_STRICT_CHK -> NETLINK_GET_STRICT_CHK 2018-12-14 11:44:31 -08:00
openat2.h tools headers UAPI: Sync openat2.h with the kernel sources 2021-03-06 16:54:22 -03:00
perf_event.h tools headers UAPI: Sync linux/perf_event.h with the kernel sources 2022-10-26 10:45:16 -03:00
pkt_cls.h treewide: uapi: Replace zero-length arrays with flexible-array members 2022-06-28 21:26:05 +02:00
pkt_sched.h sch_htb: Hierarchical QoS hardware offload 2021-01-22 20:41:29 -08:00
prctl.h tools headers UAPI: Sync linux/prctl.h with the kernel sources 2022-06-19 11:42:25 -03:00
sched.h tools headers UAPI: Sync sched.h with the kernel 2020-04-14 09:01:08 -03:00
seg6.h treewide: uapi: Replace zero-length arrays with flexible-array members 2022-06-28 21:26:05 +02:00
seg6_local.h selftests/bpf: missing headers test_lwt_seg6local 2018-05-28 17:41:00 +02:00
stat.h tools headers uapi: Sync linux/stat.h with the kernel sources 2022-10-25 17:40:48 -03:00
stddef.h tools/headers: Pull in stddef.h to uapi to fix BPF selftests build in CI 2022-11-03 13:45:21 +01:00
tcp.h bpf: Remove extra lock_sock for TCP_ZEROCOPY_RECEIVE 2021-01-20 14:23:00 -08:00
tls.h bpf, tls: add tls header to tools infrastructure 2018-10-16 08:10:01 -07:00
types.h tools/bpf: Move linux/types.h for selftests and bpftool 2020-03-13 20:56:34 +01:00
usbdevice_fs.h treewide: uapi: Replace zero-length arrays with flexible-array members 2022-06-28 21:26:05 +02:00
vhost.h tools include UAPI: Sync linux/vhost.h with the kernel sources 2022-08-19 15:30:34 -03:00