[PATCH v3 2/4] lib: sbi_pmu: fix integer overflow and zero-address in event_get_info
Anup Patel
anup at brainfault.org
Sun Oct 25 22:04:12 PDT 2026
On Thu, Sep 10, 2026 at 10:56 AM liutong <liutong at iscas.ac.cn> wrote:
>
> sbi_pmu_event_get_info() computes the shared memory size as
> num_events * sizeof(struct sbi_pmu_event_info) before num_events is
> validated. The product can wrap, in which case the domain check runs
> against a truncated size while the loop below still iterates over the
> original count, that is, past the region that was checked.
>
> A shmem_phys_lo of zero is also accepted, which leaves the loop writing
> at address 0.
>
> Check num_events against the largest value that cannot wrap, and reject
> a zero address, both before the multiplication.
>
> Fixes: e4345842168b ("lib: sbi_pmu: Implement SBI PMU event info function")
> Signed-off-by: liutong <liutong at iscas.ac.cn>
> ---
> Previously sent as [PATCH v2 4/6].
>
> Changes in v3:
> - Rebased onto current master
> - Commit message reworded; the code is unchanged from v2
> - Split into this series
>
> lib/sbi/sbi_pmu.c | 10 +++++++++-
> 1 file changed, 9 insertions(+), 1 deletion(-)
>
> diff --git a/lib/sbi/sbi_pmu.c b/lib/sbi/sbi_pmu.c
> index e79f6b60..54da5c24 100644
> --- a/lib/sbi/sbi_pmu.c
> +++ b/lib/sbi/sbi_pmu.c
> @@ -1074,7 +1074,7 @@ int sbi_pmu_ctr_get_info(uint32_t cidx, unsigned long *ctr_info)
> int sbi_pmu_event_get_info(unsigned long shmem_phys_lo, unsigned long shmem_phys_hi,
> unsigned long num_events, unsigned long flags)
> {
> - unsigned long shmem_size = num_events * sizeof(struct sbi_pmu_event_info);
> + unsigned long shmem_size;
> int i, j, event_type;
> struct sbi_pmu_event_info *einfo;
> struct sbi_pmu_hart_state *phs = pmu_thishart_state_ptr();
> @@ -1089,6 +1089,14 @@ int sbi_pmu_event_get_info(unsigned long shmem_phys_lo, unsigned long shmem_phys
> if (!num_events || (shmem_phys_lo & 0xF))
> return SBI_ERR_INVALID_PARAM;
>
> + if (!shmem_phys_lo)
> + return SBI_ERR_INVALID_ADDRESS;
RISC-V platforms can have DRAM starting at 0x0 so this check is not valid.
> +
> + if (num_events > ((unsigned long)-1) / sizeof(struct sbi_pmu_event_info))
Use "-1UL" instead of "(unsigned long)-1"
> + return SBI_ERR_INVALID_PARAM;
> +
> + shmem_size = num_events * sizeof(struct sbi_pmu_event_info);
> +
> /*
> * On RV32, the M-mode can only access the first 4GB of
> * the physical address space because M-mode does not have
> --
> 2.34.1
>
>
> --
> opensbi mailing list
> opensbi at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/opensbi
Otherwise, LGTM. I will take care of the above comments
at the time of merging.
Reviewed-by: Anup Patel <anup at brainfault.org>
Applied this patch to the riscv/opensbi repo.
Thanks,
Anup
More information about the opensbi
mailing list