Skip to content

Commit

Permalink
[ubsan] Support varlen arrays at end of struct as [1] or []
Browse files Browse the repository at this point in the history
The --enable-ubsan configure feature complains when we index variable
length arrays at the end of some structs because the arrays size is
defined to be 1. Newer C compilers support declaring these as
variable-sized using [] in the struct member type definition, which also
quiets the UBSAN complaint. Test for this support in configure and use
it if it is supported by the compiler.

Signed-off-by: Coleman Kane <ckane@colemankane.org>
  • Loading branch information
ckane committed Aug 12, 2023
1 parent 8e20e0f commit f9a4a86
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 4 deletions.
27 changes: 27 additions & 0 deletions config/zfs-build.m4
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ AC_DEFUN([ZFS_AC_CONFIG_ALWAYS], [
ZFS_AC_CONFIG_ALWAYS_CPPCHECK
ZFS_AC_CONFIG_ALWAYS_SHELLCHECK
ZFS_AC_CONFIG_ALWAYS_PARALLEL
ZFS_AC_CONFIG_ALWAYS_CC_VARSIZE_ARRAY_IN_STRUCT
])

AC_DEFUN([ZFS_AC_CONFIG], [
Expand Down Expand Up @@ -630,3 +631,29 @@ AC_DEFUN([ZFS_AC_PACKAGE], [
ZFS_AC_ALIEN
])
])

dnl #
dnl # Test whether C compiler supports variable-length array at the
dnl # end of a struct definition, and if it needs a constant or not
dnl # declaring a size
dnl #
AC_DEFUN([ZFS_AC_CONFIG_ALWAYS_CC_VARSIZE_ARRAY_IN_STRUCT], [
AC_MSG_CHECKING(
[if C compiler handles empty-index var-length array members])
AC_COMPILE_IFELSE([AC_LANG_SOURCE([
struct s {
int a;
int v[];
};
struct s test_array __attribute__((unused));
])], [
AC_MSG_RESULT([yes])
AC_DEFINE([VARLEN_ARRAY_IDX], [],
[Index to use for variable-length array struct members])
], [
AC_MSG_RESULT([no])
AC_DEFINE([VARLEN_ARRAY_IDX], 1,
[Index to use for variable-length array struct members])
])
])
7 changes: 5 additions & 2 deletions include/sys/sa_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,11 @@ typedef struct sa_hdr_phys {
*
*/
uint16_t sa_layout_info;
uint16_t sa_lengths[1]; /* optional sizes for variable length attrs */
/* ... Data follows the lengths. */
uint16_t sa_lengths[VARLEN_ARRAY_IDX];
/*
* optional sizes for variable length attrs
* ... Data follows the lengths.
*/
} sa_hdr_phys_t;

#define SA_HDR_LAYOUT_NUM(hdr) BF32_GET(hdr->sa_layout_info, 0, 10)
Expand Down
2 changes: 1 addition & 1 deletion include/sys/zap_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ typedef struct mzap_phys {
uint64_t mz_salt;
uint64_t mz_normflags;
uint64_t mz_pad[5];
mzap_ent_phys_t mz_chunk[1];
mzap_ent_phys_t mz_chunk[VARLEN_ARRAY_IDX];
/* actually variable size depending on block size */
} mzap_phys_t;

Expand Down
2 changes: 1 addition & 1 deletion include/sys/zap_leaf.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ typedef struct zap_leaf_phys {
* with the ZAP_LEAF_CHUNK() macro.
*/

uint16_t l_hash[1];
uint16_t l_hash[VARLEN_ARRAY_IDX];
} zap_leaf_phys_t;

typedef union zap_leaf_chunk {
Expand Down

0 comments on commit f9a4a86

Please sign in to comment.