diff options
author | Christoph Müllner <christoph.muellner@vrull.eu> | 2024-06-14 20:37:04 +0200 |
---|---|---|
committer | Christoph Müllner <christoph.muellner@vrull.eu> | 2024-06-15 12:12:00 +0200 |
commit | 3fe255fd3f9b7f93c69d11d4bb0963793fc5edd4 (patch) | |
tree | af87256e6ceff7084a0bb5ef19ce845c9839ab24 | |
parent | 6b2fc15d225552caf49c10401a4a0037df92d0b0 (diff) | |
download | gcc-3fe255fd3f9b7f93c69d11d4bb0963793fc5edd4.zip gcc-3fe255fd3f9b7f93c69d11d4bb0963793fc5edd4.tar.gz gcc-3fe255fd3f9b7f93c69d11d4bb0963793fc5edd4.tar.bz2 |
riscv: Allocate enough space to strcpy() string
I triggered an ICE on Ubuntu 24.04 when compiling code that uses
function attributes. Looking into the sources shows that we have
a systematic issue in the attribute handling code:
* we determine the length with strlen() (excluding the terminating null)
* we allocate a buffer with this length
* we copy the original string using strcpy() (incl. the terminating null)
To quote the man page of strcpy():
"The programmer is responsible for allocating a destination buffer
large enough, that is, strlen(src) + 1."
The ICE looks like this:
*** buffer overflow detected ***: terminated
xtheadmempair_bench.c:14:1: internal compiler error: Aborted
14 | {
| ^
0xaf3b99 crash_signal
/home/ubuntu/src/gcc/scaleff/gcc/toplev.cc:319
0xe5b957 strcpy
/usr/include/riscv64-linux-gnu/bits/string_fortified.h:79
0xe5b957 riscv_process_target_attr
/home/ubuntu/src/gcc/scaleff/gcc/config/riscv/riscv-target-attr.cc:339
0xe5baaf riscv_process_target_attr
/home/ubuntu/src/gcc/scaleff/gcc/config/riscv/riscv-target-attr.cc:314
0xe5bc5f riscv_option_valid_attribute_p(tree_node*, tree_node*, tree_node*, int)
/home/ubuntu/src/gcc/scaleff/gcc/config/riscv/riscv-target-attr.cc:389
0x6a31e5 handle_target_attribute
/home/ubuntu/src/gcc/scaleff/gcc/c-family/c-attribs.cc:5915
0x5d3a07 decl_attributes(tree_node**, tree_node*, int, tree_node*)
/home/ubuntu/src/gcc/scaleff/gcc/attribs.cc:900
0x5db403 c_decl_attributes
/home/ubuntu/src/gcc/scaleff/gcc/c/c-decl.cc:5501
0x5e8965 start_function(c_declspecs*, c_declarator*, tree_node*)
/home/ubuntu/src/gcc/scaleff/gcc/c/c-decl.cc:10562
0x6318ed c_parser_declaration_or_fndef
/home/ubuntu/src/gcc/scaleff/gcc/c/c-parser.cc:2914
0x63a8ad c_parser_external_declaration
/home/ubuntu/src/gcc/scaleff/gcc/c/c-parser.cc:2048
0x63b219 c_parser_translation_unit
/home/ubuntu/src/gcc/scaleff/gcc/c/c-parser.cc:1902
0x63b219 c_parse_file()
/home/ubuntu/src/gcc/scaleff/gcc/c/c-parser.cc:27277
0x68fec5 c_common_parse_file()
/home/ubuntu/src/gcc/scaleff/gcc/c-family/c-opts.cc:1311
Please submit a full bug report, with preprocessed source (by using -freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
gcc/ChangeLog:
* config/riscv/riscv-target-attr.cc (riscv_target_attr_parser::parse_arch):
Fix allocation size of buffer.
(riscv_process_one_target_attr): Likewise.
(riscv_process_target_attr): Likewise.
(cherry picked from commit 6762d5738b02d84ad3f51e89979b48acb68db65b)
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
-rw-r--r-- | gcc/config/riscv/riscv-target-attr.cc | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/gcc/config/riscv/riscv-target-attr.cc b/gcc/config/riscv/riscv-target-attr.cc index 1a73d69..19eb7b0 100644 --- a/gcc/config/riscv/riscv-target-attr.cc +++ b/gcc/config/riscv/riscv-target-attr.cc @@ -109,7 +109,7 @@ riscv_target_attr_parser::parse_arch (const char *str) { /* Parsing the extension list like "+<ext>[,+<ext>]*". */ size_t len = strlen (str); - std::unique_ptr<char[]> buf (new char[len]); + std::unique_ptr<char[]> buf (new char[len+1]); char *str_to_check = buf.get (); strcpy (str_to_check, str); const char *token = strtok_r (str_to_check, ",", &str_to_check); @@ -247,7 +247,7 @@ riscv_process_one_target_attr (char *arg_str, return false; } - std::unique_ptr<char[]> buf (new char[len]); + std::unique_ptr<char[]> buf (new char[len+1]); char *str_to_check = buf.get(); strcpy (str_to_check, arg_str); @@ -334,7 +334,7 @@ riscv_process_target_attr (tree fndecl, tree args, location_t loc, return false; } - std::unique_ptr<char[]> buf (new char[len]); + std::unique_ptr<char[]> buf (new char[len+1]); char *str_to_check = buf.get (); strcpy (str_to_check, TREE_STRING_POINTER (args)); |