https://gcc.gnu.org/g:2d6f1ca17f25b28da8f8d83622f0e029da2340e7

commit r16-11-g2d6f1ca17f25b28da8f8d83622f0e029da2340e7
Author: 翁愷邑 <kaiweng9...@gmail.com>
Date:   Thu Apr 17 16:24:20 2025 -0600

    [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.

Diff:
---
 gcc/config/riscv/riscv-target-attr.cc | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/gcc/config/riscv/riscv-target-attr.cc 
b/gcc/config/riscv/riscv-target-attr.cc
index 1d968655f95d..8ad3025579b2 100644
--- a/gcc/config/riscv/riscv-target-attr.cc
+++ b/gcc/config/riscv/riscv-target-attr.cc
@@ -257,11 +257,7 @@ riscv_target_attr_parser::update_settings (struct 
gcc_options *opts) const
     {
       std::string local_arch = m_subset_list->to_string (true);
       const char* local_arch_str = local_arch.c_str ();
-      struct cl_target_option *default_opts
-       = TREE_TARGET_OPTION (target_option_default_node);
-      if (opts->x_riscv_arch_string != default_opts->x_riscv_arch_string)
-       free (CONST_CAST (void *, (const void *) opts->x_riscv_arch_string));
-      opts->x_riscv_arch_string = xstrdup (local_arch_str);
+      opts->x_riscv_arch_string = ggc_strdup (local_arch_str);
 
       riscv_set_arch_by_subset_list (m_subset_list, opts);
     }

Reply via email to