All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] PCI: dwc: Fix potential NULL dereference
@ 2024-03-28 18:01 Aleksandr Mishin
  2024-03-28 18:32 ` Bjorn Helgaas
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Aleksandr Mishin @ 2024-03-28 18:01 UTC (permalink / raw)
  To: Jonathan Chocron
  Cc: Aleksandr Mishin, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Rob Herring, Bjorn Helgaas, linux-pci, linux-kernel, lvc-project

In al_pcie_config_prepare() resource_list_first_type() may return
NULL which is later dereferenced. Fix this bug by adding NULL check.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 0f71c60ffd26 ("PCI: dwc: Remove storing of PCI resources")
Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru>
---
 drivers/pci/controller/dwc/pcie-al.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c
index 6dfdda59f328..29bc99d48295 100644
--- a/drivers/pci/controller/dwc/pcie-al.c
+++ b/drivers/pci/controller/dwc/pcie-al.c
@@ -252,7 +252,12 @@ static void al_pcie_config_prepare(struct al_pcie *pcie)
 	u8 secondary_bus;
 	u32 cfg_control;
 	u32 reg;
-	struct resource *bus = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS)->res;
+
+	struct resource_entry *ft = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS); 
+	if (!ft)
+		return;
+
+	struct resource *bus = ft->res;
 
 	target_bus_cfg = &pcie->target_bus_cfg;
 
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] PCI: dwc: Fix potential NULL dereference
  2024-03-28 18:01 [PATCH] PCI: dwc: Fix potential NULL dereference Aleksandr Mishin
@ 2024-03-28 18:32 ` Bjorn Helgaas
  2024-04-25  9:45 ` [PATCH v2] PCI: dwc: al: " Aleksandr Mishin
  2024-05-03 12:57 ` [PATCH v3] PCI: dwc: al: Check IORESOURCE_BUS existence during PCIe config preparation Aleksandr Mishin
  2 siblings, 0 replies; 4+ messages in thread
From: Bjorn Helgaas @ 2024-03-28 18:32 UTC (permalink / raw)
  To: Aleksandr Mishin
  Cc: Jonathan Chocron, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Rob Herring, Bjorn Helgaas, linux-pci, linux-kernel, lvc-project

The subject line should be:

  PCI: al: ...

since this fix is specific to the "al" driver, not generic to "dwc".

On Thu, Mar 28, 2024 at 09:01:26PM +0300, Aleksandr Mishin wrote:
> In al_pcie_config_prepare() resource_list_first_type() may return
> NULL which is later dereferenced. Fix this bug by adding NULL check.
> 
> Found by Linux Verification Center (linuxtesting.org) with SVACE.
> 
> Fixes: 0f71c60ffd26 ("PCI: dwc: Remove storing of PCI resources")
> Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru>
> ---
>  drivers/pci/controller/dwc/pcie-al.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c
> index 6dfdda59f328..29bc99d48295 100644
> --- a/drivers/pci/controller/dwc/pcie-al.c
> +++ b/drivers/pci/controller/dwc/pcie-al.c
> @@ -252,7 +252,12 @@ static void al_pcie_config_prepare(struct al_pcie *pcie)
>  	u8 secondary_bus;
>  	u32 cfg_control;
>  	u32 reg;
> -	struct resource *bus = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS)->res;
> +
> +	struct resource_entry *ft = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS); 
> +	if (!ft)
> +		return;

I don't think this is right.  If we don't have an IORESOURCE_BUS
resource and we just silently return here, we will not write the
CFG_CONTROL register.  It looks essential that CFG_CONTROL be set, so
if we can't do that, the .probe() should fail.

But I think we are actually guaranteed that there is an IORESOURCE_BUS
resource because this path fabricates one if the "bus-range" DT
property doesn't exist:

 al_pcie_probe
    dw_pcie_host_init
      devm_pci_alloc_host_bridge
        devm_of_pci_bridge_init
          pci_parse_request_of_pci_ranges
            devm_of_pci_get_host_bridge_resources
              err = of_pci_parse_bus_range
                if (err)
                  bus_range->flags = IORESOURCE_BUS  # <--

I wouldn't necessarily object to doing something like other drivers
do:

  gen_pci_init
    bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
    if (!bus)
      return ERR_PTR(-ENODEV);

  xilinx_cpm_pcie_probe
    bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
    if (!bus)
      return -ENODEV;

But it would have to lead to .probe() failing, not just a silent
skipping of CFG_CONTROL setup.

> +	struct resource *bus = ft->res;
>  
>  	target_bus_cfg = &pcie->target_bus_cfg;
>  
> -- 
> 2.30.2
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2] PCI: dwc: al: Fix potential NULL dereference
  2024-03-28 18:01 [PATCH] PCI: dwc: Fix potential NULL dereference Aleksandr Mishin
  2024-03-28 18:32 ` Bjorn Helgaas
@ 2024-04-25  9:45 ` Aleksandr Mishin
  2024-05-03 12:57 ` [PATCH v3] PCI: dwc: al: Check IORESOURCE_BUS existence during PCIe config preparation Aleksandr Mishin
  2 siblings, 0 replies; 4+ messages in thread
From: Aleksandr Mishin @ 2024-04-25  9:45 UTC (permalink / raw)
  To: Jonathan Chocron
  Cc: Aleksandr Mishin, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Rob Herring, Bjorn Helgaas, linux-pci, linux-kernel, lvc-project

In al_pcie_config_prepare() resource_list_first_type() may return
NULL which is later dereferenced. Fix this bug by adding NULL check.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Fixes: 0f71c60ffd26 ("PCI: dwc: Remove storing of PCI resources")
Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru>
---
v2: Add return code processing

 drivers/pci/controller/dwc/pcie-al.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c
index 6dfdda59f328..933854c3575b 100644
--- a/drivers/pci/controller/dwc/pcie-al.c
+++ b/drivers/pci/controller/dwc/pcie-al.c
@@ -242,18 +242,24 @@ static struct pci_ops al_child_pci_ops = {
 	.write = pci_generic_config_write,
 };
 
-static void al_pcie_config_prepare(struct al_pcie *pcie)
+static int al_pcie_config_prepare(struct al_pcie *pcie)
 {
 	struct al_pcie_target_bus_cfg *target_bus_cfg;
 	struct dw_pcie_rp *pp = &pcie->pci->pp;
 	unsigned int ecam_bus_mask;
+	struct resource_entry *ft;
 	u32 cfg_control_offset;
+	struct resource *bus;
 	u8 subordinate_bus;
 	u8 secondary_bus;
 	u32 cfg_control;
 	u32 reg;
-	struct resource *bus = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS)->res;
 
+	ft = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS);
+	if (!ft)
+		return -EINVAL;
+
+	bus = ft->res;
 	target_bus_cfg = &pcie->target_bus_cfg;
 
 	ecam_bus_mask = (pcie->ecam_size >> PCIE_ECAM_BUS_SHIFT) - 1;
@@ -287,6 +293,8 @@ static void al_pcie_config_prepare(struct al_pcie *pcie)
 	       FIELD_PREP(CFG_CONTROL_SEC_BUS_MASK, secondary_bus);
 
 	al_pcie_controller_writel(pcie, cfg_control_offset, reg);
+
+	return 0;
 }
 
 static int al_pcie_host_init(struct dw_pcie_rp *pp)
@@ -305,7 +313,9 @@ static int al_pcie_host_init(struct dw_pcie_rp *pp)
 	if (rc)
 		return rc;
 
-	al_pcie_config_prepare(pcie);
+	rc = al_pcie_config_prepare(pcie);
+	if (rc < 0)
+		return rc;
 
 	return 0;
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3] PCI: dwc: al: Check IORESOURCE_BUS existence during PCIe config preparation
  2024-03-28 18:01 [PATCH] PCI: dwc: Fix potential NULL dereference Aleksandr Mishin
  2024-03-28 18:32 ` Bjorn Helgaas
  2024-04-25  9:45 ` [PATCH v2] PCI: dwc: al: " Aleksandr Mishin
@ 2024-05-03 12:57 ` Aleksandr Mishin
  2 siblings, 0 replies; 4+ messages in thread
From: Aleksandr Mishin @ 2024-05-03 12:57 UTC (permalink / raw)
  To: Jonathan Chocron
  Cc: Aleksandr Mishin, Lorenzo Pieralisi, Krzysztof Wilczyński,
	Rob Herring, Bjorn Helgaas, linux-pci, linux-kernel, lvc-project,
	Bjorn Helgaas

If IORESOURCE_BUS is not provided in Device Tree it will be fabricated
in of_pci_parse_bus_range(). So NULL pointer dereference will not occur.
But other drivers do this check. So it can be added for code consistency.

Found by Linux Verification Center (linuxtesting.org) with SVACE.

Suggested-by: Bjorn Helgaas <helgaas@kernel.org>
Signed-off-by: Aleksandr Mishin <amishin@t-argos.ru>
---
v1->v2: Add return code processing as suggested by Bjorn
v2->v3: Return -ENODEV instead of -EINVAL

 drivers/pci/controller/dwc/pcie-al.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-al.c b/drivers/pci/controller/dwc/pcie-al.c
index 6dfdda59f328..643115f74092 100644
--- a/drivers/pci/controller/dwc/pcie-al.c
+++ b/drivers/pci/controller/dwc/pcie-al.c
@@ -242,18 +242,24 @@ static struct pci_ops al_child_pci_ops = {
 	.write = pci_generic_config_write,
 };
 
-static void al_pcie_config_prepare(struct al_pcie *pcie)
+static int al_pcie_config_prepare(struct al_pcie *pcie)
 {
 	struct al_pcie_target_bus_cfg *target_bus_cfg;
 	struct dw_pcie_rp *pp = &pcie->pci->pp;
 	unsigned int ecam_bus_mask;
+	struct resource_entry *ft;
 	u32 cfg_control_offset;
+	struct resource *bus;
 	u8 subordinate_bus;
 	u8 secondary_bus;
 	u32 cfg_control;
 	u32 reg;
-	struct resource *bus = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS)->res;
 
+	ft = resource_list_first_type(&pp->bridge->windows, IORESOURCE_BUS);
+	if (!ft)
+		return -ENODEV;
+
+	bus = ft->res;
 	target_bus_cfg = &pcie->target_bus_cfg;
 
 	ecam_bus_mask = (pcie->ecam_size >> PCIE_ECAM_BUS_SHIFT) - 1;
@@ -287,6 +293,8 @@ static void al_pcie_config_prepare(struct al_pcie *pcie)
 	       FIELD_PREP(CFG_CONTROL_SEC_BUS_MASK, secondary_bus);
 
 	al_pcie_controller_writel(pcie, cfg_control_offset, reg);
+
+	return 0;
 }
 
 static int al_pcie_host_init(struct dw_pcie_rp *pp)
@@ -305,7 +313,9 @@ static int al_pcie_host_init(struct dw_pcie_rp *pp)
 	if (rc)
 		return rc;
 
-	al_pcie_config_prepare(pcie);
+	rc = al_pcie_config_prepare(pcie);
+	if (rc)
+		return rc;
 
 	return 0;
 }
-- 
2.30.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-05-03 13:09 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-28 18:01 [PATCH] PCI: dwc: Fix potential NULL dereference Aleksandr Mishin
2024-03-28 18:32 ` Bjorn Helgaas
2024-04-25  9:45 ` [PATCH v2] PCI: dwc: al: " Aleksandr Mishin
2024-05-03 12:57 ` [PATCH v3] PCI: dwc: al: Check IORESOURCE_BUS existence during PCIe config preparation Aleksandr Mishin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.