Add compiler option -fstrict-flex-arrays=1 Currently, every trailing array regardless of its declared bound is exempt from -Warray-bounds, __builtin_object_size/_FORTIFY_SOURCE, and -fsanitize=bounds. -fstrict-flex-arrays=1 says that only arrays declared with bounds [], [0], or [1] can be flexible array members (which are then mostly exempt from array bounds checking); for all other arrays, the declared size is taken as is for bounds checking, which is what we want.
This applies to a large number of structs in the tree, for example - struct pg_hmac_ctx - fe_scram_state - struct XidCache - struct RelPathStr ... which can now be checked properly. Ideally, we'd want to use the maximum level -fstrict-flex-arrays=3, which would also disqualify flexible array members declared with bounds [0] or [1]. But we do need the [1] variant in a few cases because standard C does not allow flexible array members as the only element in a struct. Affected are: - struct RevmapContents - struct ReplicationSlotCtlData - union pgresult_data Also: - struct sqlda_struct (bound by external API specification) Turning on -fstrict-flex-arrays=3 for these would conjure undefined behavior. One piece of code needs to be adjusted: JsonValueList has an array declared as [2] (via BASE_JVL_ITEMS) but addresses it as a flexible-length array in some circumstances. Change this to an anonymous union with one branch having the original size [2], to keep local variables sized the same as before, and one branch of size [1], which effectively makes this a flexible-array member under -fstrict-flex-arrays=1. We can't make it a fully flexible-array member [], because JsonValueList is also used for a field in the middle of JsonTablePlanState, which is not allowed in standard C. There is one structure with a genuine trailing one-element array: - WordEntryPosVector1 By staying with -fstrict-flex-arrays=1 we would miss out on bounds checking on that one. Also provide an attribute macro pg_attribute_strict_flex_array that allows overriding the strict flex array level for a particular struct. Use that to annotate WordEntryPosVector1. Note that clang supports the command-line option but not the attribute, so we can only use this to optionally raise the level for some structs, but we can't do the opposite of having a higher global level and lower it for some exceptions. Reviewed-by: Tristan Partin <[email protected]> Reviewed-by: Greg Burd <[email protected]> Discussion: https://www.postgresql.org/message-id/flat/c79da9e1-965d-4530-9e3e-84b8bde134ec%40eisentraut.org Branch ------ master Details ------- https://git.postgresql.org/pg/commitdiff/a625e153b7d2f0e1c81955d13f2fc8de472bc082 Modified Files -------------- configure | 92 +++++++++++++++++++++++++++++++++++ configure.ac | 3 ++ meson.build | 2 + src/backend/utils/adt/jsonpath_exec.c | 16 +++++- src/include/c.h | 19 ++++++++ src/include/tsearch/ts_type.h | 2 +- src/tools/pgindent/pgindent | 1 + 7 files changed, 133 insertions(+), 2 deletions(-)
