linux-stable/tools/include/uapi/linux
Kees Cook 896880ff30 bpf: Replace bpf_lpm_trie_key 0-length array with flexible array
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
2024-02-29 22:52:43 +01: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-02-29 22:52:43 +01:00
bpf_common.h
bpf_perf_event.h
btf.h bpf: Add btf enum64 support 2022-06-07 10:20:42 -07:00
const.h tools headers UAPI: Sync the linux/const.h with the kernel headers 2023-05-10 14:19:20 -03:00
erspan.h
ethtool.h tools: include: Add ethtool_drvinfo definition to UAPI header 2021-08-24 14:48:40 -07:00
fadvise.h
fcntl.h tools headers uapi: Sync linux/fcntl.h with the kernel sources 2023-07-11 12:29:23 -03:00
filter.h
fs.h fs/proc/task_mmu: report SOFT_DIRTY bits through the PAGEMAP_SCAN ioctl 2023-12-10 16:51:35 -08:00
fscrypt.h tools headers UAPI: Update tools's copy of fscrypt.h header 2023-11-22 10:57:46 -08:00
hw_breakpoint.h Move bp_type_idx to include/linux/hw_breakpoint.h 2023-03-10 21:05:16 +01:00
if_link.h tools: Sync if_link uapi header 2023-10-24 16:06:43 -07: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 option to calculate TX checksum in SW 2023-11-29 14:59:40 -08:00
in.h tools headers UAPI: Sync the linux/in.h with the kernel sources 2023-05-26 16:03:27 -03:00
io_uring.h tools headers: Grab copy of io_uring.h 2023-10-19 16:42:03 -06:00
kcmp.h
kvm.h tools headers UAPI: Update tools's copy of kvm.h header 2023-11-22 10:57:46 -08:00
mman.h tools headers UAPI: Sync files changed by new cachestat syscall with the kernel sources 2023-07-11 11:41:15 -03:00
mount.h tools headers UAPI: Update tools's copy of mount.h header 2023-11-22 10:57:46 -08:00
netdev.h netdev 2023-12-18 16:46:08 -08:00
netlink.h
openat2.h
perf_event.h tools headers UAPI: Sync include/uapi/linux/perf_event.h header with the kernel 2023-11-06 18:13:34 -03:00
pkt_cls.h net/sched: Remove uapi support for tcindex classifier 2024-01-02 14:25:51 +00:00
pkt_sched.h net/sched: Remove uapi support for CBQ qdisc 2024-01-02 14:25:51 +00:00
prctl.h mm: add a NO_INHERIT flag to the PR_SET_MDWE prctl 2023-10-06 14:44:11 -07:00
sched.h
seccomp.h tools headers UAPI: Copy seccomp.h to be able to build 'perf bench' in older systems 2023-09-13 08:48:48 -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
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
tls.h
types.h
usbdevice_fs.h treewide: uapi: Replace zero-length arrays with flexible-array members 2022-06-28 21:26:05 +02:00
vhost.h tools headers UAPI: Update tools's copy of vhost.h header 2023-11-22 10:57:46 -08:00