From a6aa289c53228d626f35420441afe03c93b2c249 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 10 Nov 2023 22:00:33 +0000 Subject: [PATCH 1/3] zend: introducing ZEND_ELEMENT_COUNT for struct's dynamic arrays. It is mostly for ubsan and helping array bound checking. --- Zend/zend_portability.h | 8 ++++++++ sapi/fpm/fpm/fpm_scoreboard.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index 87d9c7de94e34..37449d2db3fa6 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -327,6 +327,14 @@ char *alloca(); # define HAVE_BUILTIN_CONSTANT_P #endif +#if __has_attribute(element_count) +#define ZEND_ELEMENT_COUNT(m) __attribute__((element_count(m))) +#elif __has_attribute(counted_by) +#define ZEND_ELEMENT_COUNT(m) __attribute__((counted_by(m))) +#else +#define ZEND_ELEMENT_COUNT(m) +#endif + #ifdef HAVE_BUILTIN_CONSTANT_P # define ZEND_CONST_COND(_condition, _default) \ (__builtin_constant_p(_condition) ? (_condition) : (_default)) diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h index c488c64bfefc4..5aeb5555133a7 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.h +++ b/sapi/fpm/fpm/fpm_scoreboard.h @@ -67,7 +67,7 @@ struct fpm_scoreboard_s { int free_proc; unsigned long int slow_rq; struct fpm_scoreboard_s *shared; - struct fpm_scoreboard_proc_s procs[]; + struct fpm_scoreboard_proc_s procs[] ZEND_ELEMENT_COUNT(nprocs); }; int fpm_scoreboard_init_main(void); From 5ebb06e5cc1c0c23d8324e6e3e5111fbfabbab36 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 10 Nov 2023 22:52:20 +0000 Subject: [PATCH 2/3] adding to a handful of flexible arrays as well --- Zend/zend_types.h | 4 ++-- sapi/phpdbg/phpdbg_list.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Zend/zend_types.h b/Zend/zend_types.h index c4a07f58874ab..b77195e9a19c2 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -139,7 +139,7 @@ typedef struct { typedef struct { uint32_t num_types; - zend_type types[1]; + zend_type types[1] ZEND_ELEMENT_COUNT(num_types); } zend_type_list; #define _ZEND_TYPE_EXTRA_FLAGS_SHIFT 25 @@ -374,7 +374,7 @@ struct _zend_string { zend_refcounted_h gc; zend_ulong h; /* hash value */ size_t len; - char val[1]; + char val[1] ZEND_ELEMENT_COUNT(len); }; typedef struct _Bucket { diff --git a/sapi/phpdbg/phpdbg_list.h b/sapi/phpdbg/phpdbg_list.h index f112157e5963a..414e786f117de 100644 --- a/sapi/phpdbg/phpdbg_list.h +++ b/sapi/phpdbg/phpdbg_list.h @@ -44,7 +44,7 @@ typedef struct { size_t len; zend_op_array op_array; uint32_t lines; - uint32_t line[1]; + uint32_t line[1] ZEND_ELEMENT_COUNT(lines); } phpdbg_file_source; #endif /* PHPDBG_LIST_H */ From 9a43fee096eb30020a2ae20ae2b0b49c394f2646 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Mon, 13 Nov 2023 06:41:13 +0000 Subject: [PATCH 3/3] few more except zend_inheritance_cache_entry since the count info is not stored in the same layout (not needed) --- Zend/Optimizer/zend_call_graph.h | 2 +- Zend/zend.h | 2 +- Zend/zend_ast.h | 2 +- Zend/zend_attributes.h | 2 +- Zend/zend_types.h | 2 +- ext/ffi/ffi.c | 2 +- ext/fileinfo/libmagic/cdf.h | 2 +- ext/opcache/jit/zend_jit_internal.h | 2 +- ext/opcache/jit/zend_jit_ir.c | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Zend/Optimizer/zend_call_graph.h b/Zend/Optimizer/zend_call_graph.h index 3a02425084d58..6174c924a291d 100644 --- a/Zend/Optimizer/zend_call_graph.h +++ b/Zend/Optimizer/zend_call_graph.h @@ -39,7 +39,7 @@ struct _zend_call_info { bool named_args; /* Function has named arguments */ bool is_prototype; /* An overridden child method may be called */ int num_args; /* Number of arguments, excluding named and variadic arguments */ - zend_send_arg_info arg_info[1]; + zend_send_arg_info arg_info[1] ZEND_ELEMENT_COUNT(num_args); }; struct _zend_func_info { diff --git a/Zend/zend.h b/Zend/zend.h index aea0a6d638dc1..d60da5f83ac11 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -95,7 +95,7 @@ typedef struct _zend_trait_method_reference { typedef struct _zend_trait_precedence { zend_trait_method_reference trait_method; uint32_t num_excludes; - zend_string *exclude_class_names[1]; + zend_string *exclude_class_names[1] ZEND_ELEMENT_COUNT(num_excludes); } zend_trait_precedence; typedef struct _zend_trait_alias { diff --git a/Zend/zend_ast.h b/Zend/zend_ast.h index 963b81e533084..b5001a9ff8f54 100644 --- a/Zend/zend_ast.h +++ b/Zend/zend_ast.h @@ -191,7 +191,7 @@ typedef struct _zend_ast_list { zend_ast_attr attr; uint32_t lineno; uint32_t children; - zend_ast *child[1]; + zend_ast *child[1] ZEND_ELEMENT_COUNT(children); } zend_ast_list; /* Lineno is stored in val.u2.lineno */ diff --git a/Zend/zend_attributes.h b/Zend/zend_attributes.h index f8635aae1d3fa..deb629d482490 100644 --- a/Zend/zend_attributes.h +++ b/Zend/zend_attributes.h @@ -58,7 +58,7 @@ typedef struct _zend_attribute { /* Parameter offsets start at 1, everything else uses 0. */ uint32_t offset; uint32_t argc; - zend_attribute_arg args[1]; + zend_attribute_arg args[1] ZEND_ELEMENT_COUNT(argc); } zend_attribute; typedef struct _zend_internal_attribute { diff --git a/Zend/zend_types.h b/Zend/zend_types.h index b77195e9a19c2..f2f538a2c2c88 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -572,7 +572,7 @@ struct _zend_resource { typedef struct { size_t num; size_t num_allocated; - struct _zend_property_info *ptr[1]; + struct _zend_property_info *ptr[1] ZEND_ELEMENT_COUNT(num); } zend_property_info_list; typedef union { diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index 05c0abfdc5841..f91092ab03b9c 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -912,7 +912,7 @@ typedef struct _zend_ffi_callback_data { ffi_cif cif; uint32_t arg_count; ffi_type *ret_type; - ffi_type *arg_types[0]; + ffi_type *arg_types[0] ZEND_ELEMENT_COUNT(arg_count); } zend_ffi_callback_data; static void zend_ffi_callback_hash_dtor(zval *zv) /* {{{ */ diff --git a/ext/fileinfo/libmagic/cdf.h b/ext/fileinfo/libmagic/cdf.h index 587bed84d916b..89f5aa8e0eb73 100644 --- a/ext/fileinfo/libmagic/cdf.h +++ b/ext/fileinfo/libmagic/cdf.h @@ -277,7 +277,7 @@ typedef struct { typedef struct { size_t cat_num; - cdf_catalog_entry_t cat_e[1]; + cdf_catalog_entry_t cat_e[1] ZEND_ELEMENT_COUNT(cat_num); } cdf_catalog_t; struct timespec; diff --git a/ext/opcache/jit/zend_jit_internal.h b/ext/opcache/jit/zend_jit_internal.h index 977cec9cc9386..6ebd85c5f1b07 100644 --- a/ext/opcache/jit/zend_jit_internal.h +++ b/ext/opcache/jit/zend_jit_internal.h @@ -538,7 +538,7 @@ struct _zend_jit_trace_stack_frame { int used_stack; int old_checked_stack; int old_peek_checked_stack; - zend_jit_trace_stack stack[1]; + zend_jit_trace_stack stack[1] ZEND_ELEMENT_COUNT(used_stack); }; #define TRACE_FRAME_SHIFT_NUM_ARGS 16 diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index c520e8ce21828..bc8831c19ca28 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -142,7 +142,7 @@ typedef struct _ir_refs { uint32_t count; uint32_t limit; - ir_ref refs[0]; + ir_ref refs[0] ZEND_ELEMENT_COUNT(count); } ir_refs; #define ir_refs_size(_n) (offsetof(ir_refs, refs) + sizeof(ir_ref) * (_n))