Whamcloud - gitweb
LU-17794 lustre: replace 0-length arrays with flexible arrays (3/3) 77/56077/4
authorJian Yu <yujian@whamcloud.com>
Wed, 21 Aug 2024 20:19:43 +0000 (13:19 -0700)
committerOleg Drokin <green@whamcloud.com>
Fri, 30 Aug 2024 06:00:50 +0000 (06:00 +0000)
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 <yujian@whamcloud.com>
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/56077
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Bruno Faccini <bfaccini@nvidia.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lnet/include/uapi/linux/lnet/lnet-dlc.h
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/tests/lutf/src/Makefile.am

index de5e9ba..919e07a 100644 (file)
@@ -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 {
index 28282f4..d4ca65c 100644 (file)
@@ -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.
index cf9998d..b661a71 100644 (file)
@@ -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);
                        };
                };
        };
index d05e31c..8259c2e 100644 (file)
@@ -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"