Fwd: [v3][PATCH 1/2] Handle component_ref to a structre/union field including C99 FAM [PR101832]

2023-02-23 Thread Qing Zhao via Gcc-patches
Ping * 2.

Hi, Joseph and Richard,

Could you please review this patch and let me know whether it’s ready for 
committing into GCC13?

This is an important bug that need to be fixed for kernel security purpose.

thanks.

Qing

Begin forwarded message:

From: Qing Zhao mailto:qing.z...@oracle.com>>
Subject: [v3][PATCH 1/2] Handle component_ref to a structre/union field 
including C99 FAM [PR101832]
Date: February 10, 2023 at 7:50:12 PM EST
To: jos...@codesourcery.com<mailto:jos...@codesourcery.com>, 
rguent...@suse.de<mailto:rguent...@suse.de>
Cc: siddh...@gotplt.org<mailto:siddh...@gotplt.org>, 
keesc...@chromium.org<mailto:keesc...@chromium.org>, 
gcc-patches@gcc.gnu.org<mailto:gcc-patches@gcc.gnu.org>, Qing Zhao 
mailto:qing.z...@oracle.com>>

GCC extension accepts the case when a struct with a C99 flexible array member
is embedded into another struct or union (possibly recursively).
__builtin_object_size should treat such struct as flexible size.

gcc/c/ChangeLog:

PR tree-optimization/101832
* c-decl.cc<http://c-decl.cc> (finish_struct): Set TYPE_INCLUDE_FLEXARRAY for
struct/union type.

gcc/cp/ChangeLog:

PR tree-optimization/101832
* module.cc<http://module.cc> (trees_out::core_bools): Stream out new bit
type_include_flexarray.
(trees_in::core_bools): Stream in new bit type_include_flexarray.

gcc/ChangeLog:

PR tree-optimization/101832
* print-tree.cc<http://print-tree.cc> (print_node): Print new bit 
type_include_flexarray.
* tree-core.h (struct tree_type_common): New bit
type_include_flexarray.
* tree-object-size.cc<http://tree-object-size.cc> (addr_object_size): Handle 
structure/union type
when it has flexible size.
* tree-streamer-in.cc<http://tree-streamer-in.cc> 
(unpack_ts_type_common_value_fields): Stream
in new bit type_include_flexarray.
* tree-streamer-out.cc<http://tree-streamer-out.cc> 
(pack_ts_type_common_value_fields): Stream
out new bit type_include_flexarray.
* tree.h (TYPE_INCLUDE_FLEXARRAY): New macro
TYPE_INCLUDE_FLEXARRAY.

gcc/testsuite/ChangeLog:

PR tree-optimization/101832
* gcc.dg/builtin-object-size-pr101832.c: New test.
---
gcc/c/c-decl.cc<http://c-decl.cc>   |  12 ++
gcc/cp/module.cc<http://module.cc>  |   2 +
gcc/print-tree.cc<http://print-tree.cc> |   5 +
.../gcc.dg/builtin-object-size-pr101832.c | 134 ++
gcc/tree-core.h   |   4 +-
gcc/tree-object-size.cc<http://tree-object-size.cc>   |  79 
+++
gcc/tree-streamer-in.cc<http://tree-streamer-in.cc>   |   1 
+
gcc/tree-streamer-out.cc<http://tree-streamer-out.cc>  |   
1 +
gcc/tree.h|   6 +
9 files changed, 215 insertions(+), 29 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c

diff --git a/gcc/c/c-decl.cc<http://c-decl.cc> 
b/gcc/c/c-decl.cc<http://c-decl.cc>
index 20e7d1855bf..741a37560b0 100644
--- a/gcc/c/c-decl.cc<http://c-decl.cc>
+++ b/gcc/c/c-decl.cc<http://c-decl.cc>
@@ -9277,6 +9277,18 @@ finish_struct (location_t loc, tree t, tree fieldlist, 
tree attributes,
  /* Set DECL_NOT_FLEXARRAY flag for FIELD_DECL x.  */
  DECL_NOT_FLEXARRAY (x) = !is_flexible_array_member_p (is_last_field, x);

+  /* Set TYPE_INCLUDE_FLEXARRAY for the context of x, t
+   * when x is an array.  */
+  if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
+ TYPE_INCLUDE_FLEXARRAY (t) = flexible_array_member_type_p (TREE_TYPE (x)) ;
+  /* Recursively set TYPE_INCLUDE_FLEXARRAY for the context of x, t
+ when x is the last field.  */
+  else if ((TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+ || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)
+   && TYPE_INCLUDE_FLEXARRAY (TREE_TYPE (x))
+   && is_last_field)
+ TYPE_INCLUDE_FLEXARRAY (t) = true;
+
  if (DECL_NAME (x)
 || RECORD_OR_UNION_TYPE_P (TREE_TYPE (x)))
saw_named_field = true;
diff --git a/gcc/cp/module.cc<http://module.cc> 
b/gcc/cp/module.cc<http://module.cc>
index ac2fe66b080..c750361b704 100644
--- a/gcc/cp/module.cc<http://module.cc>
+++ b/gcc/cp/module.cc<http://module.cc>
@@ -5371,6 +5371,7 @@ trees_out::core_bools (tree t)
  WB (t->type_common.lang_flag_5);
  WB (t->type_common.lang_flag_6);
  WB (t->type_common.typeless_storage);
+  WB (t->type_common.type_include_flexarray);
}

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
@@ -5551,6 +5552,7 @@ trees_in::core_bools (tree t)
  RB (t->type_common.lang_flag_5);
  RB (t->type_common.lang_flag_6);
  RB (t->type_common.typeless_storage);
+  RB (t->type_common.type_include_flexarray);
}

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
diff --git a/gcc/print-tree.cc<http://print-tree.cc> 
b

Re: [v3][PATCH 1/2] Handle component_ref to a structre/union field including C99 FAM [PR101832]

2023-02-17 Thread Qing Zhao via Gcc-patches
Ping…

Qing

> On Feb 10, 2023, at 7:50 PM, Qing Zhao  wrote:
> 
> GCC extension accepts the case when a struct with a C99 flexible array member
> is embedded into another struct or union (possibly recursively).
> __builtin_object_size should treat such struct as flexible size.
> 
> gcc/c/ChangeLog:
> 
>   PR tree-optimization/101832
>   * c-decl.cc (finish_struct): Set TYPE_INCLUDE_FLEXARRAY for
>   struct/union type.
> 
> gcc/cp/ChangeLog:
> 
>   PR tree-optimization/101832
>   * module.cc (trees_out::core_bools): Stream out new bit
>   type_include_flexarray.
>   (trees_in::core_bools): Stream in new bit type_include_flexarray.
> 
> gcc/ChangeLog:
> 
>   PR tree-optimization/101832
>   * print-tree.cc (print_node): Print new bit type_include_flexarray.
>   * tree-core.h (struct tree_type_common): New bit
>   type_include_flexarray.
>   * tree-object-size.cc (addr_object_size): Handle structure/union type
>   when it has flexible size.
>   * tree-streamer-in.cc (unpack_ts_type_common_value_fields): Stream
>   in new bit type_include_flexarray.
>   * tree-streamer-out.cc (pack_ts_type_common_value_fields): Stream
>   out new bit type_include_flexarray.
>   * tree.h (TYPE_INCLUDE_FLEXARRAY): New macro
>   TYPE_INCLUDE_FLEXARRAY.
> 
> gcc/testsuite/ChangeLog:
> 
>   PR tree-optimization/101832
>   * gcc.dg/builtin-object-size-pr101832.c: New test.
> ---
> gcc/c/c-decl.cc   |  12 ++
> gcc/cp/module.cc  |   2 +
> gcc/print-tree.cc |   5 +
> .../gcc.dg/builtin-object-size-pr101832.c | 134 ++
> gcc/tree-core.h   |   4 +-
> gcc/tree-object-size.cc   |  79 +++
> gcc/tree-streamer-in.cc   |   1 +
> gcc/tree-streamer-out.cc  |   1 +
> gcc/tree.h|   6 +
> 9 files changed, 215 insertions(+), 29 deletions(-)
> create mode 100644 gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c
> 
> diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
> index 20e7d1855bf..741a37560b0 100644
> --- a/gcc/c/c-decl.cc
> +++ b/gcc/c/c-decl.cc
> @@ -9277,6 +9277,18 @@ finish_struct (location_t loc, tree t, tree fieldlist, 
> tree attributes,
>   /* Set DECL_NOT_FLEXARRAY flag for FIELD_DECL x.  */
>   DECL_NOT_FLEXARRAY (x) = !is_flexible_array_member_p (is_last_field, x);
> 
> +  /* Set TYPE_INCLUDE_FLEXARRAY for the context of x, t
> +   * when x is an array.  */
> +  if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
> + TYPE_INCLUDE_FLEXARRAY (t) = flexible_array_member_type_p (TREE_TYPE 
> (x)) ;
> +  /* Recursively set TYPE_INCLUDE_FLEXARRAY for the context of x, t
> +  when x is the last field.  */
> +  else if ((TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
> + || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)
> +&& TYPE_INCLUDE_FLEXARRAY (TREE_TYPE (x))
> +&& is_last_field)
> + TYPE_INCLUDE_FLEXARRAY (t) = true;
> +
>   if (DECL_NAME (x)
> || RECORD_OR_UNION_TYPE_P (TREE_TYPE (x)))
>   saw_named_field = true;
> diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> index ac2fe66b080..c750361b704 100644
> --- a/gcc/cp/module.cc
> +++ b/gcc/cp/module.cc
> @@ -5371,6 +5371,7 @@ trees_out::core_bools (tree t)
>   WB (t->type_common.lang_flag_5);
>   WB (t->type_common.lang_flag_6);
>   WB (t->type_common.typeless_storage);
> +  WB (t->type_common.type_include_flexarray);
> }
> 
>   if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
> @@ -5551,6 +5552,7 @@ trees_in::core_bools (tree t)
>   RB (t->type_common.lang_flag_5);
>   RB (t->type_common.lang_flag_6);
>   RB (t->type_common.typeless_storage);
> +  RB (t->type_common.type_include_flexarray);
> }
> 
>   if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
> diff --git a/gcc/print-tree.cc b/gcc/print-tree.cc
> index 1f3afcbbc86..efacdb7686f 100644
> --- a/gcc/print-tree.cc
> +++ b/gcc/print-tree.cc
> @@ -631,6 +631,11 @@ print_node (FILE *file, const char *prefix, tree node, 
> int indent,
> && TYPE_CXX_ODR_P (node))
>   fputs (" cxx-odr-p", file);
> 
> +  if ((code == RECORD_TYPE
> +|| code == UNION_TYPE)
> +   && TYPE_INCLUDE_FLEXARRAY (node))
> + fputs (" include-flexarray", file);
> +
>   /* The transparent-union flag is used for different things in
>different nodes.  */
>   if ((code == UNION_TYPE || code == RECORD_TYPE)
> diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c 
> b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c
> new file mode 100644
> index 000..60078e11634
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c
> @@ -0,0 +1,134 @@
> +/* PR 101832: 
> +   GCC extension accepts the case when a struct with a C99 flexible array
> +   member is embedded into 

[v3][PATCH 1/2] Handle component_ref to a structre/union field including C99 FAM [PR101832]

2023-02-10 Thread Qing Zhao via Gcc-patches
GCC extension accepts the case when a struct with a C99 flexible array member
is embedded into another struct or union (possibly recursively).
__builtin_object_size should treat such struct as flexible size.

gcc/c/ChangeLog:

PR tree-optimization/101832
* c-decl.cc (finish_struct): Set TYPE_INCLUDE_FLEXARRAY for
struct/union type.

gcc/cp/ChangeLog:

PR tree-optimization/101832
* module.cc (trees_out::core_bools): Stream out new bit
type_include_flexarray.
(trees_in::core_bools): Stream in new bit type_include_flexarray.

gcc/ChangeLog:

PR tree-optimization/101832
* print-tree.cc (print_node): Print new bit type_include_flexarray.
* tree-core.h (struct tree_type_common): New bit
type_include_flexarray.
* tree-object-size.cc (addr_object_size): Handle structure/union type
when it has flexible size.
* tree-streamer-in.cc (unpack_ts_type_common_value_fields): Stream
in new bit type_include_flexarray.
* tree-streamer-out.cc (pack_ts_type_common_value_fields): Stream
out new bit type_include_flexarray.
* tree.h (TYPE_INCLUDE_FLEXARRAY): New macro
TYPE_INCLUDE_FLEXARRAY.

gcc/testsuite/ChangeLog:

PR tree-optimization/101832
* gcc.dg/builtin-object-size-pr101832.c: New test.
---
 gcc/c/c-decl.cc   |  12 ++
 gcc/cp/module.cc  |   2 +
 gcc/print-tree.cc |   5 +
 .../gcc.dg/builtin-object-size-pr101832.c | 134 ++
 gcc/tree-core.h   |   4 +-
 gcc/tree-object-size.cc   |  79 +++
 gcc/tree-streamer-in.cc   |   1 +
 gcc/tree-streamer-out.cc  |   1 +
 gcc/tree.h|   6 +
 9 files changed, 215 insertions(+), 29 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 20e7d1855bf..741a37560b0 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -9277,6 +9277,18 @@ finish_struct (location_t loc, tree t, tree fieldlist, 
tree attributes,
   /* Set DECL_NOT_FLEXARRAY flag for FIELD_DECL x.  */
   DECL_NOT_FLEXARRAY (x) = !is_flexible_array_member_p (is_last_field, x);
 
+  /* Set TYPE_INCLUDE_FLEXARRAY for the context of x, t
+   * when x is an array.  */
+  if (TREE_CODE (TREE_TYPE (x)) == ARRAY_TYPE)
+   TYPE_INCLUDE_FLEXARRAY (t) = flexible_array_member_type_p (TREE_TYPE 
(x)) ;
+  /* Recursively set TYPE_INCLUDE_FLEXARRAY for the context of x, t
+when x is the last field.  */
+  else if ((TREE_CODE (TREE_TYPE (x)) == RECORD_TYPE
+   || TREE_CODE (TREE_TYPE (x)) == UNION_TYPE)
+  && TYPE_INCLUDE_FLEXARRAY (TREE_TYPE (x))
+  && is_last_field)
+   TYPE_INCLUDE_FLEXARRAY (t) = true;
+
   if (DECL_NAME (x)
  || RECORD_OR_UNION_TYPE_P (TREE_TYPE (x)))
saw_named_field = true;
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index ac2fe66b080..c750361b704 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -5371,6 +5371,7 @@ trees_out::core_bools (tree t)
   WB (t->type_common.lang_flag_5);
   WB (t->type_common.lang_flag_6);
   WB (t->type_common.typeless_storage);
+  WB (t->type_common.type_include_flexarray);
 }
 
   if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
@@ -5551,6 +5552,7 @@ trees_in::core_bools (tree t)
   RB (t->type_common.lang_flag_5);
   RB (t->type_common.lang_flag_6);
   RB (t->type_common.typeless_storage);
+  RB (t->type_common.type_include_flexarray);
 }
 
   if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
diff --git a/gcc/print-tree.cc b/gcc/print-tree.cc
index 1f3afcbbc86..efacdb7686f 100644
--- a/gcc/print-tree.cc
+++ b/gcc/print-tree.cc
@@ -631,6 +631,11 @@ print_node (FILE *file, const char *prefix, tree node, int 
indent,
  && TYPE_CXX_ODR_P (node))
fputs (" cxx-odr-p", file);
 
+  if ((code == RECORD_TYPE
+  || code == UNION_TYPE)
+ && TYPE_INCLUDE_FLEXARRAY (node))
+   fputs (" include-flexarray", file);
+
   /* The transparent-union flag is used for different things in
 different nodes.  */
   if ((code == UNION_TYPE || code == RECORD_TYPE)
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c 
b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c
new file mode 100644
index 000..60078e11634
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-pr101832.c
@@ -0,0 +1,134 @@
+/* PR 101832: 
+   GCC extension accepts the case when a struct with a C99 flexible array
+   member is embedded into another struct (possibly recursively).
+   __builtin_object_size will treat such struct as flexible size.
+   However, when a structure with non-C99 flexible array member, i.e, trailing
+   [0], [1], or [4],