[binutils-gdb] RISC-V: avoid buffer underrun in subset parsing
Jan Beulich
jbeulich@sourceware.org
Fri Jun 5 09:13:57 GMT 2026
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=952275b4a6c44fee709cb47236df9f604327d1d4
commit 952275b4a6c44fee709cb47236df9f604327d1d4
Author: Jan Beulich <jbeulich@suse.com>
Date: Fri Jun 5 11:11:25 2026 +0200
RISC-V: avoid buffer underrun in subset parsing
In both instances 'p' can be the first character. Inspecting the character
immediately ahead of it is then UB.
To increase similarity between the two checks (each), also move the
increment of q past the check for the (bogus) "<number>p" ending.
Correct indentation in nearby code, where it being wrong is actively
misleading.
Reviewed-by: Jiawei <jiawei@iscas.ac.cn>
Diff:
---
bfd/elfxx-riscv.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 8e56322b512..c0439102e8d 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -2113,25 +2113,27 @@ riscv_parse_extensions (riscv_parse_subset_t *rps,
find_any_version = true;
else if (find_any_version
&& !find_minor_version
+ && q > subset
&& *q == 'p'
&& ISDIGIT (*(q - 1)))
- find_minor_version = true;
+ find_minor_version = true;
else
break;
}
- 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 (q > subset && *q == 'p' && ISDIGIT (*(q - 1)))
{
- *q = '\0';
+ q[1] = '\0';
rps->error_handler
(_("%s: invalid prefixed ISA extension `%s' ends with <number>p"),
arch, subset);
free (subset);
return NULL;
}
+
+ q++;
}
int major_version = RISCV_UNKNOWN_VERSION;
@@ -2672,20 +2674,19 @@ riscv_update_subset1 (riscv_parse_subset_t *rps,
find_any_version = true;
else if (find_any_version
&& !find_minor_version
+ && q > subset
&& *q == 'p'
&& ISDIGIT (*(q - 1)))
find_minor_version = true;
else
break;
}
- 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 (len > 1 && *(q - 1) == 'p' && ISDIGIT (*(q - 2)))
+ if (q > subset && *q == 'p' && ISDIGIT (*(q - 1)))
{
- *q = '\0';
+ q[1] = '\0';
rps->error_handler
(_("%sinvalid ISA extension `%s' ends with <number>p in %s `%s'"),
errmsg_internal, subset, errmsg_caller, implicit_exts);
@@ -2693,6 +2694,9 @@ riscv_update_subset1 (riscv_parse_subset_t *rps,
return false;
}
+ if (len > 0)
+ q++;
+
end_of_version =
riscv_parsing_subset_version (q, &major_version, &minor_version);
*q = '\0';
More information about the Binutils-cvs
mailing list