diff mbox series

[4/4] perf/smmuv3: fix crash when platdata not specified

Message ID 20200712163341.61410-5-ajaykumar.rs@samsung.com (mailing list archive)
State New, archived
Headers show
Series Add DT support for arm_smmuv3_pmu driver | expand

Commit Message

Ajay Kumar July 12, 2020, 4:33 p.m. UTC
The arm_smmuv3_pmu driver assumes platform data is always
available and exposes a possible NULL pointer deferencing
at the below line.

model = *(u32 *)dev_get_platdata(smmu_pmu->dev);

This patch fixes the bug by adding a check prior to the
deferencing of the platform data pointer.

Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
---
 drivers/perf/arm_smmuv3_pmu.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

Comments

Jonathan Cameron July 13, 2020, 8:46 a.m. UTC | #1
On Sun, 12 Jul 2020 22:03:41 +0530
Ajay Kumar <ajaykumar.rs@samsung.com> wrote:

> The arm_smmuv3_pmu driver assumes platform data is always
> available and exposes a possible NULL pointer deferencing
> at the below line.
> 
> model = *(u32 *)dev_get_platdata(smmu_pmu->dev);
> 
> This patch fixes the bug by adding a check prior to the
> deferencing of the platform data pointer.
> 
> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
> ---
>  drivers/perf/arm_smmuv3_pmu.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
> index 25feab718c20..f7a27ae2f8d8 100644
> --- a/drivers/perf/arm_smmuv3_pmu.c
> +++ b/drivers/perf/arm_smmuv3_pmu.c
> @@ -710,9 +710,10 @@ static void smmu_pmu_reset(struct smmu_pmu *smmu_pmu)
>  
>  static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
>  {
> -	u32 model;
> +	u32 model = 0;

Use the generic model define.  Sure it's 0, but good to make it clear what
the meaning of this default is.

It also seems likely you hit this because of you were using dt.
If so, it seems 'odd' to be running a function explicitly mentioning acpi in
it's name.

Also, should do this before introducing support that might lead to this path
so as not to cause bisection problems.

Jonathan


>  
> -	model = *(u32 *)dev_get_platdata(smmu_pmu->dev);
> +	if (dev_get_platdata(smmu_pmu->dev))
> +		model = *(u32 *)dev_get_platdata(smmu_pmu->dev);
>  
>  	switch (model) {
>  	case IORT_SMMU_V3_PMCG_HISI_HIP08:
Robin Murphy July 13, 2020, 9:46 a.m. UTC | #2
On 2020-07-12 17:33, Ajay Kumar wrote:
> The arm_smmuv3_pmu driver assumes platform data is always
> available and exposes a possible NULL pointer deferencing
> at the below line.
> 
> model = *(u32 *)dev_get_platdata(smmu_pmu->dev);
> 
> This patch fixes the bug by adding a check prior to the
> deferencing of the platform data pointer.
> 
> Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
> ---
>   drivers/perf/arm_smmuv3_pmu.c | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
> index 25feab718c20..f7a27ae2f8d8 100644
> --- a/drivers/perf/arm_smmuv3_pmu.c
> +++ b/drivers/perf/arm_smmuv3_pmu.c
> @@ -710,9 +710,10 @@ static void smmu_pmu_reset(struct smmu_pmu *smmu_pmu)
>   
>   static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
>   {
> -	u32 model;
> +	u32 model = 0;
>   
> -	model = *(u32 *)dev_get_platdata(smmu_pmu->dev);
> +	if (dev_get_platdata(smmu_pmu->dev))
> +		model = *(u32 *)dev_get_platdata(smmu_pmu->dev);

As I commented on the other series, ideally this could be something like:

	if (dev->of_node)
		model = of_device_get_match_data(dev->of_node);
	else
		model = *(u32 *)dev_get_platdata(dev); /* from IORT */

(and lose the "acpi_" from the function name, obviously)

Robin.

>   
>   	switch (model) {
>   	case IORT_SMMU_V3_PMCG_HISI_HIP08:
>
diff mbox series

Patch

diff --git a/drivers/perf/arm_smmuv3_pmu.c b/drivers/perf/arm_smmuv3_pmu.c
index 25feab718c20..f7a27ae2f8d8 100644
--- a/drivers/perf/arm_smmuv3_pmu.c
+++ b/drivers/perf/arm_smmuv3_pmu.c
@@ -710,9 +710,10 @@  static void smmu_pmu_reset(struct smmu_pmu *smmu_pmu)
 
 static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
 {
-	u32 model;
+	u32 model = 0;
 
-	model = *(u32 *)dev_get_platdata(smmu_pmu->dev);
+	if (dev_get_platdata(smmu_pmu->dev))
+		model = *(u32 *)dev_get_platdata(smmu_pmu->dev);
 
 	switch (model) {
 	case IORT_SMMU_V3_PMCG_HISI_HIP08: