From: Bjorn Helgaas <helgaas@kernel.org>
To: Marco Nenciarini <mnencia@kcore.it>
Cc: "Bjorn Helgaas" <bhelgaas@google.com>,
"Michał Winiarski" <michal.winiarski@intel.com>,
"Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Eric Chanudet" <echanude@redhat.com>,
"Alex Williamson" <alex@shazbot.org>,
"Lukas Wunner" <lukas@wunner.de>,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org
Subject: Re: [PATCH] PCI/IOV: Fix out-of-bounds access in sriov_restore_vf_rebar_state()
Date: Thu, 16 Apr 2026 17:57:45 -0500 [thread overview]
Message-ID: <20260416225745.GA41850@bhelgaas> (raw)
In-Reply-To: <20260408163922.1740497-1-mnencia@kcore.it>
[+cc Rafael, Eric, Alex, Lukas, generic pci_restore_state() question]
On Wed, Apr 08, 2026 at 06:39:22PM +0200, Marco Nenciarini wrote:
> sriov_restore_vf_rebar_state() extracts bar_idx from the VF Resizable
> BAR control register using a 3-bit field (PCI_VF_REBAR_CTRL_BAR_IDX,
> bits 0-2), which yields values in the range 0-7. This value is then
> used to index into dev->sriov->barsz[], which has PCI_SRIOV_NUM_BARS
> (6) entries.
>
> If the PCI config space read returns garbage data (e.g. 0xffffffff when
> the device is no longer accessible on the bus), bar_idx is 7, causing
> an out-of-bounds array access. UBSAN reports this as:
>
> UBSAN: array-index-out-of-bounds in drivers/pci/iov.c:948:51
> index 7 is out of range for type 'resource_size_t [6]'
>
> This was observed on an NVIDIA RTX PRO 1000 GPU (GB207GLM) that fell
> off the PCIe bus during a failed GC6 power state exit. The subsequent
> pci_restore_state() call triggered the UBSAN splat in
> sriov_restore_vf_rebar_state() since all config space reads returned
> 0xffffffff.
I think all of pci_restore_state() is problematic for all devices, not
just this GPU. If these config reads fail, all the previous config
writes probably failed (silently) as well.
And we have this weird retry loop in pci_restore_config_dword():
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pci/pci.c?id=v7.0#n1766,
which was originally added by
https://git.kernel.org/linus/26f41062f28d ("PCI: check for pci bar
restore completion and retry") to fix an actual problem:
On some OEM systems, pci_restore_state() is called while FLR has not
yet completed. As a result, PCI BAR register restore is not
successful. This fix reads back the restored value and compares it
with saved value and re-tries 10 times before giving up.
This just gives me the heebie-jeebies. If we still need this retry
loop, it means all the previous state restoration (PCIe, LTR, ASPM,
IOV, PRI, ATS, DPC, etc.) probably failed, and we end up with a device
where the BARs got restored but none of the previous stuff. That
sounds like a mess.
> Add a bounds check on bar_idx before using it as an array index to
> prevent the out-of-bounds access.
>
> Fixes: 5a8f77e24a30 ("PCI/IOV: Restore VF resizable BAR state after reset")
> Cc: stable@vger.kernel.org
> Signed-off-by: Marco Nenciarini <mnencia@kcore.it>
> ---
> Cc: Michał Winiarski <michal.winiarski@intel.com>
> Cc: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
>
> drivers/pci/iov.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
> index 00784a60b..521f2cb64 100644
> --- a/drivers/pci/iov.c
> +++ b/drivers/pci/iov.c
> @@ -946,6 +946,8 @@ static void sriov_restore_vf_rebar_state(struct pci_dev *dev)
>
> pci_read_config_dword(dev, pos + PCI_VF_REBAR_CTRL, &ctrl);
> bar_idx = FIELD_GET(PCI_VF_REBAR_CTRL_BAR_IDX, ctrl);
> + if (bar_idx >= PCI_SRIOV_NUM_BARS)
> + continue;
> size = pci_rebar_bytes_to_size(dev->sriov->barsz[bar_idx]);
> ctrl &= ~PCI_VF_REBAR_CTRL_BAR_SIZE;
> ctrl |= FIELD_PREP(PCI_VF_REBAR_CTRL_BAR_SIZE, size);
> --
> 2.47.3
>
next prev parent reply other threads:[~2026-04-16 22:57 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-08 16:39 [PATCH] PCI/IOV: Fix out-of-bounds access in sriov_restore_vf_rebar_state() Marco Nenciarini
2026-04-14 13:34 ` Michał Winiarski
2026-04-16 22:42 ` Bjorn Helgaas
2026-04-16 22:57 ` Bjorn Helgaas [this message]
2026-04-17 4:57 ` Lukas Wunner
2026-04-17 13:24 ` [PATCH v2 0/2] PCI: Guard Resizable BAR restore against unreachable devices Marco Nenciarini
2026-04-17 13:24 ` [PATCH v2 1/2] PCI: Skip Resizable BAR restore on read error Marco Nenciarini
2026-04-17 13:24 ` [PATCH v2 2/2] PCI/IOV: Skip VF " Marco Nenciarini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260416225745.GA41850@bhelgaas \
--to=helgaas@kernel.org \
--cc=alex@shazbot.org \
--cc=bhelgaas@google.com \
--cc=echanude@redhat.com \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lukas@wunner.de \
--cc=michal.winiarski@intel.com \
--cc=mnencia@kcore.it \
--cc=rafael@kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox