From 37acaa912f34d68f37f788d5478e04838b040fc9 Mon Sep 17 00:00:00 2001 From: Jian Yu Date: Wed, 21 Aug 2024 13:19:43 -0700 Subject: [PATCH] LU-17794 lustre: replace 0-length arrays with flexible arrays (3/3) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patch replaces 0-length arrays with flexible arrays to resolve the UBSAN array-index-out-of-bounds runtime warnings. Most replacement of 0-length arrays with flexible arrays requires no special handling. Simply removing the “0” in the array declaration is sufficient. 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. This was wrapped in Linux with the DECLARE_FLEX_ARRAY() macro. This patch also work-arounds SWIG limitations with flexible arrays. Test-Parameters: optional mdtcount=4 mdscount=2 \ clientdistro=ubuntu2404 testgroup=full-dne-part-1 Test-Parameters: optional mdtcount=4 mdscount=2 \ clientdistro=ubuntu2404 testgroup=full-dne-part-2 Test-Parameters: optional mdtcount=4 mdscount=2 \ clientdistro=ubuntu2404 testgroup=full-dne-part-3 Change-Id: I873663373332d63fb79137163149d42663f34705 Signed-off-by: Jian Yu Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56077 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: James Simmons Reviewed-by: Bruno Faccini Reviewed-by: Oleg Drokin --- lnet/include/uapi/linux/lnet/lnet-dlc.h | 6 +++--- lustre/include/uapi/linux/lustre/lustre_idl.h | 23 ----------------------- lustre/include/uapi/linux/lustre/lustre_user.h | 25 ++++++++++++++++++++++++- lustre/tests/lutf/src/Makefile.am | 4 ++++ 4 files changed, 31 insertions(+), 27 deletions(-) diff --git a/lnet/include/uapi/linux/lnet/lnet-dlc.h b/lnet/include/uapi/linux/lnet/lnet-dlc.h index de5e9ba..919e07a 100644 --- a/lnet/include/uapi/linux/lnet/lnet-dlc.h +++ b/lnet/include/uapi/linux/lnet/lnet-dlc.h @@ -141,7 +141,7 @@ struct lnet_ioctl_net_config { char ni_interface[LNET_MAX_STR_LEN]; __u32 ni_status; __u32 ni_cpts[LNET_MAX_SHOW_NUM_CPT]; - char cfg_bulk[0]; + char cfg_bulk[]; }; #define LNET_TINY_BUF_IDX 0 @@ -205,7 +205,7 @@ struct lnet_ioctl_config_data { } cfg_buffers; } cfg_config_u; - char cfg_bulk[0]; + char cfg_bulk[]; }; struct lnet_ioctl_comm_count { @@ -281,7 +281,7 @@ struct lnet_ioctl_config_ni { __u32 lic_idx; __s32 lic_dev_cpt; char pad[4]; - char lic_bulk[0]; + char lic_bulk[]; }; struct lnet_peer_ni_credit_info { diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index 28282f4..d4ca65c 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -116,29 +116,6 @@ extern "C" { /* #define DVS_PORTAL 63 */ /* reserved for Cray DVS - spitzcor@cray.com, roe@cray.com, n8851@cray.com */ -#ifndef DECLARE_FLEX_ARRAY -#ifdef __cplusplus -/* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */ -#define DECLARE_FLEX_ARRAY(T, member) T member[0] -#else -/** - * 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 -#endif /* DECLARE_FLEX_ARRAY */ - /** * Describes a range of sequence, lsr_start is included but lsr_end is * not in the range. diff --git a/lustre/include/uapi/linux/lustre/lustre_user.h b/lustre/include/uapi/linux/lustre/lustre_user.h index cf9998d..b661a71 100644 --- a/lustre/include/uapi/linux/lustre/lustre_user.h +++ b/lustre/include/uapi/linux/lustre/lustre_user.h @@ -111,6 +111,29 @@ typedef struct stat lstat_t; #define fstatat_f fstatat #endif +#ifndef DECLARE_FLEX_ARRAY +#ifdef __cplusplus +/* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */ +#define DECLARE_FLEX_ARRAY(T, member) T member[0] +#else +/** + * 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 +#endif /* DECLARE_FLEX_ARRAY */ + #ifndef STATX_BASIC_STATS /* * Timestamp structure for the timestamps in struct statx. @@ -2922,7 +2945,7 @@ struct ll_foreign_symlink_upcall_item { /* internal storage of constant string */ char *string; /* upcall stores constant string in a raw */ - char bytestring[0]; + DECLARE_FLEX_ARRAY(char, bytestring); }; }; }; diff --git a/lustre/tests/lutf/src/Makefile.am b/lustre/tests/lutf/src/Makefile.am index d05e31c..8259c2e 100644 --- a/lustre/tests/lutf/src/Makefile.am +++ b/lustre/tests/lutf/src/Makefile.am @@ -106,6 +106,10 @@ liblutf_connect.so : dlc_glue: echo "generating liblnetconfig.i" $(PYTHON) $(GEN_SWIG_INTF_PY) $(top_builddir) + echo "work-around SWIG limitations with flexible arrays" + sed -i '1i\%immutable lnet_ioctl_net_config::cfg_bulk;\n' $(LNETCONFIG_I) + sed -i '1i\%immutable lnet_ioctl_config_data::cfg_bulk;' $(LNETCONFIG_I) + sed -i '1i\%immutable lnet_ioctl_config_ni::lic_bulk;' $(LNETCONFIG_I) echo "generating liblndconfig_wrap.c" $(SWIG) -python $(DLC_SWIG_FLAGS) $(DLC_SWIG_INCLUDES) $(LNETCONFIG_I) echo "building liblnetconfig_wrap.c" -- 1.8.3.1