[PATCH 15/19] RISC-V: avoid buffer underrun in subset parsing
Jiawei
jiawei@iscas.ac.cn
Wed Apr 29 12:37:43 GMT 2026
> 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.
> ---
> Why is it that P is recognized as an extension when there's no other
> support there for it?
>
LGTM.
Regarding the question about P, the P extension is still in draft state:
https://github.com/riscv/riscv-p-spec
We already have some downstream experimental support for it. Once the P
specification is frozen, we plan to prepare and submit the corresponding
binutils support upstream.
So I think the P-related cleanup can be handled separately from this UB fix.
>
> --- a/bfd/elfxx-riscv.c
> +++ b/bfd/elfxx-riscv.c
> @@ -2113,25 +2113,27 @@ riscv_parse_extensions (riscv_parse_subs
> 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
> 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 ends with <number>p in %s `%s'"),
> errmsg_internal, errmsg_caller, implicit_exts);
> @@ -2693,6 +2694,9 @@ riscv_update_subset1 (riscv_parse_subset
> return false;
> }
>
> + if (len > 0)
> + q++;
> +
> end_of_version =
> riscv_parsing_subset_version (q, &major_version, &minor_version);
> *q = '\0';
>
Reviewed-by: Jiawei <jiawei@iscas.ac.cn>
More information about the Binutils
mailing list