Commit 7500d4c3 authored by Aleksandr Mishin's avatar Aleksandr Mishin Committed by Yang Yingliang
Browse files

PCI: keystone: Fix NULL pointer dereference in case of DT error in ks_pcie_setup_rc_app_regs()

mainline inclusion
from mainline-v6.11-rc1
commit a231707a91f323af1e5d9f1722055ec2fc1c7775
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAKQ54
CVE: CVE-2024-43823

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a231707a91f323af1e5d9f1722055ec2fc1c7775

---------------------------

If IORESOURCE_MEM is not provided in Device Tree due to
any error, resource_list_first_type() will return NULL and
pci_parse_request_of_pci_ranges() will just emit a warning.

This will cause a NULL pointer dereference. Fix this bug by adding NULL
return check.

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

Fixes: 0f71c60f ("PCI: dwc: Remove storing of PCI resources")
Link: https://lore.kernel.org/linux-pci/20240505061517.11527-1-amishin@t-argos.ru


Suggested-by: default avatarBjorn Helgaas <helgaas@kernel.org>
Suggested-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: default avatarAleksandr Mishin <amishin@t-argos.ru>
Signed-off-by: default avatarKrzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Conflicts:
	drivers/pci/controller/dwc/pci-keystone.c
[yyl: adjust context]
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parent 05db3a6e
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -391,17 +391,22 @@ static void ks_pcie_clear_dbi_mode(struct keystone_pcie *ks_pcie)
	} while (val & DBI_CS2);
}

static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
static int ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
{
	u32 val;
	struct dw_pcie *pci = ks_pcie->pci;
	struct pcie_port *pp = &pci->pp;
	u32 num_viewport = pci->num_viewport;
	u64 start, end;
	struct resource_entry *entry;
	struct resource *mem;
	u64 start, end;
	int i;

	mem = resource_list_first_type(&pp->bridge->windows, IORESOURCE_MEM)->res;
	entry = resource_list_first_type(&pp->bridge->windows, IORESOURCE_MEM);
	if (!entry)
		return -ENODEV;

	mem = entry->res;
	start = mem->start;
	end = mem->end;

@@ -412,7 +417,7 @@ static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
	ks_pcie_clear_dbi_mode(ks_pcie);

	if (ks_pcie->is_am6)
		return;
		return 0;

	val = ilog2(OB_WIN_SIZE);
	ks_pcie_app_writel(ks_pcie, OB_SIZE, val);
@@ -429,6 +434,8 @@ static void ks_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
	val = ks_pcie_app_readl(ks_pcie, CMD_STATUS);
	val |= OB_XLAT_EN_VAL;
	ks_pcie_app_writel(ks_pcie, CMD_STATUS, val);

	return 0;
}

static void __iomem *ks_pcie_other_map_bus(struct pci_bus *bus,
@@ -825,7 +832,10 @@ static int __init ks_pcie_host_init(struct pcie_port *pp)
	dw_pcie_setup_rc(pp);

	ks_pcie_stop_link(pci);
	ks_pcie_setup_rc_app_regs(ks_pcie);
	ret = ks_pcie_setup_rc_app_regs(ks_pcie);
	if (ret)
		return ret;

	writew(PCI_IO_RANGE_TYPE_32 | (PCI_IO_RANGE_TYPE_32 << 8),
			pci->dbi_base + PCI_IO_BASE);