diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:06:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 10:06:00 +0000 |
commit | b15a952c52a6825376d3e7f6c1bf5c886c6d8b74 (patch) | |
tree | 1500f2f8f276908a36d8126cb632c0d6b1276764 /debian/patches/bugfix/all/stddef-Introduce-DECLARE_FLEX_ARRAY-helper.patch | |
parent | Adding upstream version 5.10.209. (diff) | |
download | linux-debian.tar.xz linux-debian.zip |
Adding debian version 5.10.209-2.debian/5.10.209-2debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches/bugfix/all/stddef-Introduce-DECLARE_FLEX_ARRAY-helper.patch')
-rw-r--r-- | debian/patches/bugfix/all/stddef-Introduce-DECLARE_FLEX_ARRAY-helper.patch | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/debian/patches/bugfix/all/stddef-Introduce-DECLARE_FLEX_ARRAY-helper.patch b/debian/patches/bugfix/all/stddef-Introduce-DECLARE_FLEX_ARRAY-helper.patch new file mode 100644 index 000000000..8f8066530 --- /dev/null +++ b/debian/patches/bugfix/all/stddef-Introduce-DECLARE_FLEX_ARRAY-helper.patch @@ -0,0 +1,156 @@ +From: Kees Cook <keescook@chromium.org> +Date: Fri, 26 Jan 2024 22:31:42 +0300 +Subject: stddef: Introduce DECLARE_FLEX_ARRAY() helper +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git/commit?id=ef8316e0e29e98d9cf7e0689ddffa37e79d33736 + +commit 3080ea5553cc909b000d1f1d964a9041962f2c5b upstream. + +There are many places where kernel code wants to have several different +typed trailing flexible arrays. This would normally be done with multiple +flexible arrays in a union, but since GCC and Clang don't (on the surface) +allow this, there have been many open-coded workarounds, usually involving +neighboring 0-element arrays at the end of a structure. For example, +instead of something like this: + +struct thing { + ... + union { + struct type1 foo[]; + struct type2 bar[]; + }; +}; + +code works around the compiler with: + +struct thing { + ... + struct type1 foo[0]; + struct type2 bar[]; +}; + +Another case is when a flexible array is wanted as the single member +within a struct (which itself is usually in a union). For example, this +would be worked around as: + +union many { + ... + struct { + struct type3 baz[0]; + }; +}; + +These kinds of work-arounds cause problems with size checks against such +zero-element arrays (for example when building with -Warray-bounds and +-Wzero-length-bounds, and with the coming FORTIFY_SOURCE improvements), +so they must all be converted to "real" flexible arrays, avoiding warnings +like this: + +fs/hpfs/anode.c: In function 'hpfs_add_sector_to_btree': +fs/hpfs/anode.c:209:27: warning: array subscript 0 is outside the bounds of an interior zero-length array 'struct bplus_internal_node[0]' [-Wzero-length-bounds] + 209 | anode->btree.u.internal[0].down = cpu_to_le32(a); + | ~~~~~~~~~~~~~~~~~~~~~~~^~~ +In file included from fs/hpfs/hpfs_fn.h:26, + from fs/hpfs/anode.c:10: +fs/hpfs/hpfs.h:412:32: note: while referencing 'internal' + 412 | struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving + | ^~~~~~~~ + +drivers/net/can/usb/etas_es58x/es58x_fd.c: In function 'es58x_fd_tx_can_msg': +drivers/net/can/usb/etas_es58x/es58x_fd.c:360:35: warning: array subscript 65535 is outside the bounds of an interior zero-length array 'u8[0]' {aka 'unsigned char[]'} [-Wzero-length-bounds] + 360 | tx_can_msg = (typeof(tx_can_msg))&es58x_fd_urb_cmd->raw_msg[msg_len]; + | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +In file included from drivers/net/can/usb/etas_es58x/es58x_core.h:22, + from drivers/net/can/usb/etas_es58x/es58x_fd.c:17: +drivers/net/can/usb/etas_es58x/es58x_fd.h:231:6: note: while referencing 'raw_msg' + 231 | u8 raw_msg[0]; + | ^~~~~~~ + +However, it _is_ entirely possible to have one or more flexible arrays +in a struct or union: it just has to be in another struct. And since it +cannot be alone in a struct, such a struct must have at least 1 other +named member -- but that member can be zero sized. Wrap all this nonsense +into the new DECLARE_FLEX_ARRAY() in support of having flexible arrays +in unions (or alone in a struct). + +As with struct_group(), since this is needed in UAPI headers as well, +implement the core there, with a non-UAPI wrapper. + +Additionally update kernel-doc to understand its existence. + +https://github.com/KSPP/linux/issues/137 + +Cc: Arnd Bergmann <arnd@arndb.de> +Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org> +Signed-off-by: Kees Cook <keescook@chromium.org> +Signed-off-by: Vasiliy Kovalev <kovalev@altlinux.org> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + include/linux/stddef.h | 13 +++++++++++++ + include/uapi/linux/stddef.h | 16 ++++++++++++++++ + scripts/kernel-doc | 3 ++- + 3 files changed, 31 insertions(+), 1 deletion(-) + +diff --git a/include/linux/stddef.h b/include/linux/stddef.h +index 938216f8ab7e..31fdbb784c24 100644 +--- a/include/linux/stddef.h ++++ b/include/linux/stddef.h +@@ -84,4 +84,17 @@ enum { + #define struct_group_tagged(TAG, NAME, MEMBERS...) \ + __struct_group(TAG, NAME, /* no attrs */, MEMBERS) + ++/** ++ * DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union ++ * ++ * @TYPE: The type of each flexible array element ++ * @NAME: The name of the flexible array member ++ * ++ * In order to have a flexible array member in a union or alone in a ++ * struct, it needs to be wrapped in an anonymous struct with at least 1 ++ * named member, but that member can be empty. ++ */ ++#define DECLARE_FLEX_ARRAY(TYPE, NAME) \ ++ __DECLARE_FLEX_ARRAY(TYPE, NAME) ++ + #endif +diff --git a/include/uapi/linux/stddef.h b/include/uapi/linux/stddef.h +index c3725b492263..7837ba4fe728 100644 +--- a/include/uapi/linux/stddef.h ++++ b/include/uapi/linux/stddef.h +@@ -28,4 +28,20 @@ + struct { MEMBERS } ATTRS; \ + struct TAG { MEMBERS } ATTRS NAME; \ + } ++ ++/** ++ * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union ++ * ++ * @TYPE: The type of each flexible array element ++ * @NAME: The name of the flexible array member ++ * ++ * In order to have a flexible array member in a union or alone in a ++ * struct, it needs to be wrapped in an anonymous struct with at least 1 ++ * named member, but that member can be empty. ++ */ ++#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \ ++ struct { \ ++ struct { } __empty_ ## NAME; \ ++ TYPE NAME[]; \ ++ } + #endif +diff --git a/scripts/kernel-doc b/scripts/kernel-doc +index 19af6dd160e6..7a04d4c05326 100755 +--- a/scripts/kernel-doc ++++ b/scripts/kernel-doc +@@ -1232,7 +1232,8 @@ sub dump_struct($$) { + $members =~ s/DECLARE_KFIFO\s*\(([^,)]+),\s*([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; + # replace DECLARE_KFIFO_PTR + $members =~ s/DECLARE_KFIFO_PTR\s*\(([^,)]+),\s*([^,)]+)\)/$2 \*$1/gos; +- ++ # replace DECLARE_FLEX_ARRAY ++ $members =~ s/(?:__)?DECLARE_FLEX_ARRAY\s*\($args,\s*$args\)/$1 $2\[\]/gos; + my $declaration = $members; + + # Split nested struct/union elements as newer ones +-- +2.43.0 + |