diff options
author | Nelson Chu <nelson.chu@sifive.com> | 2021-11-21 23:31:32 -0800 |
---|---|---|
committer | Nelson Chu <nelson.chu@sifive.com> | 2021-11-22 17:27:13 +0800 |
commit | 577bf39f10c6d50a52866eb8fc32d6d1e34bb215 (patch) | |
tree | e775d36f2573a76d0bb0e0cbbcd909166daec0e5 /bfd | |
parent | bab31d145160cd4dec7b9ad0e79346382ebf8385 (diff) | |
download | gdb-577bf39f10c6d50a52866eb8fc32d6d1e34bb215.zip gdb-577bf39f10c6d50a52866eb8fc32d6d1e34bb215.tar.gz gdb-577bf39f10c6d50a52866eb8fc32d6d1e34bb215.tar.bz2 |
RISC-V: PR28610, Fix ASAN heap-buffer-overflow error in riscv_update_subset.
The architecture parser in riscv_update_subset shouldn't check (or access)
the pointer space which doesn't exist.
bfd/
pr 28610
* elfxx-riscv.c (riscv_update_subset): The architecture parser
shouldn't access the pointer space which doesn't exist.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/elfxx-riscv.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index b8da40c..73a99b5 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -2211,6 +2211,9 @@ riscv_update_subset (riscv_parse_subset_t *rps, { const char *p = str; + if (p == NULL) + return false; + do { int major_version = RISCV_UNKNOWN_VERSION; @@ -2236,10 +2239,13 @@ riscv_update_subset (riscv_parse_subset_t *rps, /* Extract the whole prefixed extension by ','. */ while (*q != '\0' && *q != ',') q++; + /* Look forward to the first letter which is not <major>p<minor>. */ bool find_any_version = false; bool find_minor_version = false; - while (1) + size_t len = q - subset; + size_t i; + for (i = len; i > 0; i--) { q--; if (ISDIGIT (*q)) @@ -2252,10 +2258,12 @@ riscv_update_subset (riscv_parse_subset_t *rps, else break; } - q++; + if (len > 0) + q++; + /* Check if the end of extension is 'p' or not. If yes, then the second letter from the end cannot be number. */ - if (*(q - 1) == 'p' && ISDIGIT (*(q - 2))) + if (len > 1 && *(q - 1) == 'p' && ISDIGIT (*(q - 2))) { *q = '\0'; rps->error_handler @@ -2264,6 +2272,7 @@ riscv_update_subset (riscv_parse_subset_t *rps, free (subset); return false; } + end_of_version = riscv_parsing_subset_version (q, &major_version, &minor_version); *q = '\0'; @@ -2305,10 +2314,6 @@ riscv_update_subset (riscv_parse_subset_t *rps, } while (*p++ == ','); - if (*(--p) != '\0') - rps->error_handler - (_("unexpected value in .option arch `%s'"), str); - riscv_parse_add_implicit_subsets (rps); return riscv_parse_check_conflicts (rps); } |