diff mbox series

[1/3] perf: RISC-V: fix access beyond allocated array

Message ID 20220623112735.357093-2-geomatsi@gmail.com (mailing list archive)
State Superseded, archived
Headers show
Series perf: RISC-V: fix access to the highest available counter | expand

Commit Message

Sergey Matyukevich June 23, 2022, 11:27 a.m. UTC
From: Sergey Matyukevich <sergey.matyukevich@syntacore.com>

Both OpenSBI and Linux driver explicitly assume that pmu counter IDs are
not expected to be contiguous. Namely, there is no hardware counter with
index 1: hardware uses that bit for TM control. However counter array is
allocated without that assumption. As a result, memory beyond allocated
array is accessed. Fix this by adding unused array element for index 1.

Signed-off-by: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
---
 drivers/perf/riscv_pmu_sbi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Atish Patra June 23, 2022, 5:50 p.m. UTC | #1
On Thu, Jun 23, 2022 at 4:27 AM Sergey Matyukevich <geomatsi@gmail.com> wrote:
>
> From: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
>
> Both OpenSBI and Linux driver explicitly assume that pmu counter IDs are
> not expected to be contiguous. Namely, there is no hardware counter with
> index 1: hardware uses that bit for TM control. However counter array is
> allocated without that assumption. As a result, memory beyond allocated
> array is accessed. Fix this by adding unused array element for index 1.
>
> Signed-off-by: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
> ---
>  drivers/perf/riscv_pmu_sbi.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index dca3537a8dcc..3e0ea564b9b8 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -453,7 +453,7 @@ static int pmu_sbi_get_ctrinfo(int nctr)
>         int i, num_hw_ctr = 0, num_fw_ctr = 0;
>         union sbi_pmu_ctr_info cinfo;
>
> -       pmu_ctr_list = kcalloc(nctr, sizeof(*pmu_ctr_list), GFP_KERNEL);
> +       pmu_ctr_list = kcalloc(nctr + 1, sizeof(*pmu_ctr_list), GFP_KERNEL);
>         if (!pmu_ctr_list)
>                 return -ENOMEM;
>
> --
> 2.36.1
>

instead of this, get_info for loop should be restricted nctr as it
should be zero indexed.

diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index f9cf6c62aaea..0722fe2869aa 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -491,7 +491,7 @@ static int pmu_sbi_get_ctrinfo(int nctr, int *num_hw_ctrs)
        if (!pmu_ctr_list)
                return -ENOMEM;

-       for (i = 0; i <= nctr; i++) {
+       for (i = 0; i < nctr; i++) {
                ret = sbi_ecall(SBI_EXT_PMU,
SBI_EXT_PMU_COUNTER_GET_INFO, i, 0, 0, 0, 0, 0);
                if (ret.error)
                        /* The logical counter ids are not expected to
be contiguous */
Sergey Matyukevich June 23, 2022, 6:10 p.m. UTC | #2
> > Both OpenSBI and Linux driver explicitly assume that pmu counter IDs are
> > not expected to be contiguous. Namely, there is no hardware counter with
> > index 1: hardware uses that bit for TM control. However counter array is
> > allocated without that assumption. As a result, memory beyond allocated
> > array is accessed. Fix this by adding unused array element for index 1.
> >
> > Signed-off-by: Sergey Matyukevich <sergey.matyukevich@syntacore.com>
> > ---
> >  drivers/perf/riscv_pmu_sbi.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> > index dca3537a8dcc..3e0ea564b9b8 100644
> > --- a/drivers/perf/riscv_pmu_sbi.c
> > +++ b/drivers/perf/riscv_pmu_sbi.c
> > @@ -453,7 +453,7 @@ static int pmu_sbi_get_ctrinfo(int nctr)
> >         int i, num_hw_ctr = 0, num_fw_ctr = 0;
> >         union sbi_pmu_ctr_info cinfo;
> >
> > -       pmu_ctr_list = kcalloc(nctr, sizeof(*pmu_ctr_list), GFP_KERNEL);
> > +       pmu_ctr_list = kcalloc(nctr + 1, sizeof(*pmu_ctr_list), GFP_KERNEL);
> >         if (!pmu_ctr_list)
> >                 return -ENOMEM;
> >
> > --
> > 2.36.1
> >
> 
> instead of this, get_info for loop should be restricted nctr as it
> should be zero indexed.
> 
> diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
> index f9cf6c62aaea..0722fe2869aa 100644
> --- a/drivers/perf/riscv_pmu_sbi.c
> +++ b/drivers/perf/riscv_pmu_sbi.c
> @@ -491,7 +491,7 @@ static int pmu_sbi_get_ctrinfo(int nctr, int *num_hw_ctrs)
>         if (!pmu_ctr_list)
>                 return -ENOMEM;
> 
> -       for (i = 0; i <= nctr; i++) {
> +       for (i = 0; i < nctr; i++) {
>                 ret = sbi_ecall(SBI_EXT_PMU,
> SBI_EXT_PMU_COUNTER_GET_INFO, i, 0, 0, 0, 0, 0);
>                 if (ret.error)
>                         /* The logical counter ids are not expected to
> be contiguous */

Well, this is going to fix immediate issue. But array size will have to
be increased by one to enable access to the highest index counter (see
the 2nd patch).

Regards,
Sergey
diff mbox series

Patch

diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index dca3537a8dcc..3e0ea564b9b8 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -453,7 +453,7 @@  static int pmu_sbi_get_ctrinfo(int nctr)
 	int i, num_hw_ctr = 0, num_fw_ctr = 0;
 	union sbi_pmu_ctr_info cinfo;
 
-	pmu_ctr_list = kcalloc(nctr, sizeof(*pmu_ctr_list), GFP_KERNEL);
+	pmu_ctr_list = kcalloc(nctr + 1, sizeof(*pmu_ctr_list), GFP_KERNEL);
 	if (!pmu_ctr_list)
 		return -ENOMEM;