]> git.ipfire.org Git - thirdparty/gcc.git/commit
[PATCH] RISC-V: Do not free a riscv_arch_string when handling target-arch attribute
author翁愷邑 <kaiweng9487@gmail.com>
Thu, 17 Apr 2025 22:24:20 +0000 (16:24 -0600)
committerJeff Law <jlaw@ventanamicro.com>
Thu, 17 Apr 2025 22:24:20 +0000 (16:24 -0600)
commit2d6f1ca17f25b28da8f8d83622f0e029da2340e7
tree11a6f93fc93723f6854b2eff506e33cedbc4bada
parent3f0eccfd90370a7c5300f92493143c7e5a66be85
[PATCH] RISC-V: Do not free a riscv_arch_string when handling target-arch attribute

The build_target_option_node() function may return a cached node when
fndecl having the same effective global_options. Therefore, freeing
memory used in target nodes can lead to a use-after-free issue, as a
target node may be shared by multiple fndecl.
This issue occurs in gcc.target/riscv/target-attr-16.c, where all
functions have the same march, but the last function tries to free its
old x_riscv_arch_string (which is shared) when processing the second
target attribute.However, the behavior of this issue depends on how the
OS handles malloc. It's very likely that xstrdup returns the old address
just freed, coincidentally hiding the issue. We can verify the issue by
forcing xstrdup to return a new address, e.g.,

-  if (opts->x_riscv_arch_string != default_opts->x_riscv_arch_string)
-    free (CONST_CAST (void *, (const void *) opts->x_riscv_arch_string));
+  // Force it to use a new address, NFCI
+  const char *tmp = opts->x_riscv_arch_string;
   opts->x_riscv_arch_string = xstrdup (local_arch_str);

+  if (tmp != default_opts->x_riscv_arch_string)
+    free (CONST_CAST (void *, (const void *) tmp));

This patch replaces xstrdup with ggc_strdup and let gc to take care of
unused strings.

gcc/ChangeLog:

* config/riscv/riscv-target-attr.cc
(riscv_target_attr_parser::update_settings):
Do not manually free any arch string.
gcc/config/riscv/riscv-target-attr.cc