When parsing the capability list make sure the offset is between the MMIO region mapped in 'regs', or else the kernel hits a page fault. Adding the check is harmless, and prevents buggy or broken systems from crashing the kernel if the capability linked list is somehow broken. Fixes: 91d898e51e60 ('pinctrl: intel: Convert capability list to features') Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- Changes since v1: - Adjust commit message. --- Cc: Mika Westerberg <mika.westerberg@xxxxxxxxxxxxxxx> Cc: Andy Shevchenko <andy@xxxxxxxxxx> Cc: Linus Walleij <linus.walleij@xxxxxxxxxx> Cc: linux-gpio@xxxxxxxxxxxxxxx --- drivers/pinctrl/intel/pinctrl-intel.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c index 59d13342caf6..d45a6994b2a3 100644 --- a/drivers/pinctrl/intel/pinctrl-intel.c +++ b/drivers/pinctrl/intel/pinctrl-intel.c @@ -1481,16 +1481,22 @@ static int intel_pinctrl_probe(struct platform_device *pdev, for (i = 0; i < pctrl->ncommunities; i++) { struct intel_community *community = &pctrl->communities[i]; + struct resource *res; void __iomem *regs; + size_t size; u32 offset; u32 value; *community = pctrl->soc->communities[i]; - regs = devm_platform_ioremap_resource(pdev, community->barno); + regs = devm_platform_get_and_ioremap_resource(pdev, + community->barno, + &res); if (IS_ERR(regs)) return PTR_ERR(regs); + size = res->end - res->start; + /* Determine community features based on the revision */ value = readl(regs + REVID); if (value == ~0u) @@ -1521,6 +1527,12 @@ static int intel_pinctrl_probe(struct platform_device *pdev, break; } offset = (value & CAPLIST_NEXT_MASK) >> CAPLIST_NEXT_SHIFT; + if (offset >= size) { + dev_err(&pdev->dev, + "wrong capability offset: %#x\n", + offset); + return -ENOENT; + } } while (offset); dev_dbg(&pdev->dev, "Community%d features: %#08x\n", i, community->features); -- 2.30.1