Re: [PATCH RFC] ALSA: Validate MMIO BARs before mapping

Aleksandr Nogikh <[email protected]>
Newsgroups dev.linux.lists.syzbot
Message-ID <CANp29Y5F5C+Px=JJH_GTgYfC6sH-GLUkgd_TPsFWxAJ=TmEdFQ@mail.gmail.com>
This patches the symptom across 12 individual ALSA drivers when the
root cause is in the PCI devres subsystem.

 `pcim_iomap_region()` wraps `pci_iomap()`, so unlike
`pci_ioremap_bar()` it does not validate `IORESOURCE_MEM`. When an I/O
BAR is mapped, subsequent MMIO accessors (`readl`/`readw`) page fault
on x86.

Rather than scattering boilerplate checks across drivers, this should
be solved centrally in the PCI core (e.g. by validating
`IORESOURCE_MEM` in `pcim_iomap_region()` or introducing a managed
`pcim_ioremap_bar()`)

On Wed, Aug 12, 2026 at 3:19 PM 'syzbot' via
syzkaller-upstream-moderation
<[email protected]> wrote:
>
> The `snd_hda_intel` driver assumes PCI BAR 0 is a memory-mapped I/O (MMIO)
> region, but it fails to verify this assumption before mapping and accessing
> it. If a device with an I/O Port BAR at BAR 0 is bound to the driver (e.g.,
> via the `new_id` sysfs interface), `pcim_iomap_region()` successfully maps
> it and returns an I/O port cookie. The driver then attempts to read from
> this address using MMIO accessors like `readw()`, which directly
> dereferences the pointer. On x86, this results in a supervisor read access
> page fault:
>
> BUG: unable to handle page fault for address: 000000000001c094
> #PF: supervisor read access in kernel mode
> #PF: error_code(0x0000) - not-present page
> RIP: 0010:readw arch/x86/include/asm/io.h:58 [inline]
> RIP: 0010:snd_hdac_reg_readw include/sound/hdaudio.h:458 [inline]
> RIP: 0010:snd_hdac_bus_parse_capabilities+0x47/0x750
> sound/hda/core/controller.c:412
> Call Trace:
>  azx_first_init sound/hda/controllers/intel.c:1936 [inline]
>  azx_probe_continue sound/hda/controllers/intel.c:2365 [inline]
>  azx_probe_work+0x85e/0x2860 sound/hda/controllers/intel.c:1737
>
> To fix this issue, verify that the BAR is an MMIO region using
> `pci_resource_is_mem()` before attempting to map it. If the BAR is not an
> MMIO region, log an error and abort the probe process with `-ENXIO`.
>
> A subsystem-wide audit revealed that several other ALSA PCI drivers use
> `pcim_iomap_region()` and subsequently use MMIO accessors on the returned
> pointer without validating the resource type. To ensure comprehensive
> protection, apply the same validation pattern to all vulnerable ALSA PCI
> drivers, including `snd_ad1889`, `snd_atiixp`, `snd_atiixp_modem`,
> `snd_au88x0`, `snd_aw2`, `snd_bt87x`, `snd_cs4281`, `snd_cs5530`,
> `snd_lola`, `snd_hdspm`, and `loongson_i2s_pci`.
>
> Fixes: 3fcaf24e5dce ("ALSA: hda: Allocate resources with device-managed APIs")
> Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot
> Reported-by: [email protected]
> Closes: https://syzkaller.appspot.com/bug?extid=10cd2d1efe8eeb604bee
> Link: https://syzkaller.appspot.com/ai_job?id=dd4258ea-3be3-4977-b597-0fc0910b0f51
> To: "Mark Brown" <[email protected]>
> To: "Clemens Ladisch" <[email protected]>
> To: "Liam Girdwood" <[email protected]>
> To: <[email protected]>
> To: <[email protected]>
> To: "Jaroslav Kysela" <[email protected]>
> To: "Takashi Iwai" <[email protected]>
> To: "Binbin Zhou" <[email protected]>
> To: "Takashi Iwai" <[email protected]>
> Cc: "Chandra Mohan Sundar" <[email protected]>
> Cc: "Kai Vehmanen" <[email protected]>
> Cc: "Kees Cook" <[email protected]>
> Cc: <[email protected]>
> Cc: "Peter Ujfalusi" <[email protected]>
> Cc: "Philipp Stanner" <[email protected]>
> Cc: "Thomas Gleixner" <[email protected]>
> Cc: =?utf-8?b?VXdlIEtsZWluZS1Lw7ZuaWcgKFRoZSBDYXBhYmxlIEh1Yik=?= <[email protected]>
> Cc: "Haotian Zhang" <[email protected]>
>
> ---
> diff --git a/sound/hda/controllers/intel.c b/sound/hda/controllers/intel.c
> index 28c55c5a2..22c2b5b42 100644
> --- a/sound/hda/controllers/intel.c
> +++ b/sound/hda/controllers/intel.c
> @@ -1926,6 +1926,11 @@ static int azx_first_init(struct azx *chip)
>         if (chip->driver_type == AZX_DRIVER_ZHAOXINHDMI)
>                 bus->polling_mode = 1;
>
> +       if (!pci_resource_is_mem(pci, 0)) {
> +               dev_err(card->dev, "Invalid PCI BAR 0: not an MMIO region\n");
> +               return -ENXIO;
> +       }
> +
>         bus->remap_addr = pcim_iomap_region(pci, 0, "ICH HD audio");
>         if (IS_ERR(bus->remap_addr))
>                 return PTR_ERR(bus->remap_addr);
> diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
> index f4ec404c0..4f208f962 100644
> --- a/sound/pci/ad1889.c
> +++ b/sound/pci/ad1889.c
> @@ -803,6 +803,11 @@ snd_ad1889_create(struct snd_card *card, struct pci_dev *pci)
>         chip->pci = pci;
>         chip->irq = -1;
>
> +       if (!pci_resource_is_mem(pci, 0)) {
> +               dev_err(card->dev, "Invalid PCI BAR 0: not an MMIO region\n");
> +               return -ENXIO;
> +       }
> +
>         /* (1) PCI resource allocation */
>         chip->iobase = pcim_iomap_region(pci, 0, card->driver);
>         if (IS_ERR(chip->iobase))
> diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
> index b738295b4..9b346b9b0 100644
> --- a/sound/pci/atiixp.c
> +++ b/sound/pci/atiixp.c
> @@ -1531,6 +1531,12 @@ static int snd_atiixp_init(struct snd_card *card, struct pci_dev *pci)
>         chip->card = card;
>         chip->pci = pci;
>         chip->irq = -1;
> +
> +       if (!pci_resource_is_mem(pci, 0)) {
> +               dev_err(card->dev, "Invalid PCI BAR 0: not an MMIO region\n");
> +               return -ENXIO;
> +       }
> +
>         chip->remap_addr = pcim_iomap_region(pci, 0, "ATI IXP AC97");
>         if (IS_ERR(chip->remap_addr))
>                 return PTR_ERR(chip->remap_addr);
> diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
> index 8aaeb197c..32a80297a 100644
> --- a/sound/pci/atiixp_modem.c
> +++ b/sound/pci/atiixp_modem.c
> @@ -1163,6 +1163,12 @@ static int snd_atiixp_init(struct snd_card *card, struct pci_dev *pci)
>         chip->card = card;
>         chip->pci = pci;
>         chip->irq = -1;
> +
> +       if (!pci_resource_is_mem(pci, 0)) {
> +               dev_err(card->dev, "Invalid PCI BAR 0: not an MMIO region\n");
> +               return -ENXIO;
> +       }
> +
>         chip->remap_addr = pcim_iomap_region(pci, 0, "ATI IXP MC97");
>         if (IS_ERR(chip->remap_addr))
>                 return PTR_ERR(chip->remap_addr);
> diff --git a/sound/pci/au88x0/au88x0.c b/sound/pci/au88x0/au88x0.c
> index bb0294579..9b2c9361a 100644
> --- a/sound/pci/au88x0/au88x0.c
> +++ b/sound/pci/au88x0/au88x0.c
> @@ -157,6 +157,11 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci)
>         chip->card = card;
>         chip->irq = -1;
>
> +       if (!pci_resource_is_mem(pci, 0)) {
> +               dev_err(card->dev, "Invalid PCI BAR 0: not an MMIO region\n");
> +               return -ENXIO;
> +       }
> +
>         // (1) PCI resource allocation
>         // Get MMIO area
>         //
> diff --git a/sound/pci/aw2/aw2-alsa.c b/sound/pci/aw2/aw2-alsa.c
> index 60a87322e..c9c7129e4 100644
> --- a/sound/pci/aw2/aw2-alsa.c
> +++ b/sound/pci/aw2/aw2-alsa.c
> @@ -223,6 +223,11 @@ static int snd_aw2_create(struct snd_card *card,
>         chip->pci = pci;
>         chip->irq = -1;
>
> +       if (!pci_resource_is_mem(pci, 0)) {
> +               dev_err(card->dev, "Invalid PCI BAR 0: not an MMIO region\n");
> +               return -ENXIO;
> +       }
> +
>         /* (1) PCI resource allocation */
>         chip->iobase_virt = pcim_iomap_region(pci, 0, "Audiowerk2");
>         if (IS_ERR(chip->iobase_virt))
> diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
> index 383def1f2..e71fe10ce 100644
> --- a/sound/pci/bt87x.c
> +++ b/sound/pci/bt87x.c
> @@ -690,6 +690,11 @@ static int snd_bt87x_create(struct snd_card *card,
>         chip->irq = -1;
>         spin_lock_init(&chip->reg_lock);
>
> +       if (!pci_resource_is_mem(pci, 0)) {
> +               dev_err(card->dev, "Invalid PCI BAR 0: not an MMIO region\n");
> +               return -ENXIO;
> +       }
> +
>         chip->mmio = pcim_iomap_region(pci, 0, "Bt87x audio");
>         if (IS_ERR(chip->mmio))
>                 return PTR_ERR(chip->mmio);
> diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
> index f51f4bb63..792a63d36 100644
> --- a/sound/pci/cs4281.c
> +++ b/sound/pci/cs4281.c
> @@ -1298,6 +1298,11 @@ static int snd_cs4281_create(struct snd_card *card,
>         }
>         chip->dual_codec = dual_codec;
>
> +       if (!pci_resource_is_mem(pci, 0) || !pci_resource_is_mem(pci, 1)) {
> +               dev_err(card->dev, "Invalid PCI BARs: not MMIO regions\n");
> +               return -ENXIO;
> +       }
> +
>         chip->ba0 = pcim_iomap_region(pci, 0, "CS4281");
>         if (IS_ERR(chip->ba0))
>                 return PTR_ERR(chip->ba0);
> diff --git a/sound/pci/cs5530.c b/sound/pci/cs5530.c
> index 292b65aa7..dc5e30947 100644
> --- a/sound/pci/cs5530.c
> +++ b/sound/pci/cs5530.c
> @@ -91,6 +91,11 @@ static int snd_cs5530_create(struct snd_card *card,
>         chip->card = card;
>         chip->pci = pci;
>
> +       if (!pci_resource_is_mem(pci, 0)) {
> +               dev_err(card->dev, "Invalid PCI BAR 0: not an MMIO region\n");
> +               return -ENXIO;
> +       }
> +
>         mem = pcim_iomap_region(pci, 0, "CS5530");
>         if (IS_ERR(mem))
>                 return PTR_ERR(mem);
> diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c
> index 34a3ba17d..fdef79879 100644
> --- a/sound/pci/lola/lola.c
> +++ b/sound/pci/lola/lola.c
> @@ -579,6 +579,11 @@ static int lola_create(struct snd_card *card, struct pci_dev *pci, int dev)
>                 chip->sample_rate_min = 16000;
>         }
>
> +       if (!pci_resource_is_mem(pci, 0) || !pci_resource_is_mem(pci, 2)) {
> +               dev_err(card->dev, "Invalid PCI BARs: not MMIO regions\n");
> +               return -ENXIO;
> +       }
> +
>         iomem = pcim_iomap_region(pci, 0, DRVNAME);
>         if (IS_ERR(iomem))
>                 return PTR_ERR(iomem);
> diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
> index d8bbedbc8..344008ff7 100644
> --- a/sound/pci/rme9652/hdspm.c
> +++ b/sound/pci/rme9652/hdspm.c
> @@ -6456,6 +6456,11 @@ static int snd_hdspm_create(struct snd_card *card,
>         int err;
>         unsigned long io_extent;
>
> +       if (!pci_resource_is_mem(pci, 0)) {
> +               dev_err(card->dev, "Invalid PCI BAR 0: not an MMIO region\n");
> +               return -ENXIO;
> +       }
> +
>         hdspm->irq = -1;
>         hdspm->card = card;
>
> diff --git a/sound/soc/loongson/loongson_i2s_pci.c b/sound/soc/loongson/loongson_i2s_pci.c
> index f5b560465..5e634d467 100644
> --- a/sound/soc/loongson/loongson_i2s_pci.c
> +++ b/sound/soc/loongson/loongson_i2s_pci.c
> @@ -41,6 +41,11 @@ static int loongson_i2s_pci_probe(struct pci_dev *pdev,
>         i2s->dev = dev;
>         pci_set_drvdata(pdev, i2s);
>
> +       if (!pci_resource_is_mem(pdev, 0)) {
> +               dev_err(dev, "Invalid PCI BAR 0: not an MMIO region\n");
> +               return -ENXIO;
> +       }
> +
>         i2s->reg_base = pcim_iomap_region(pdev, 0, DRIVER_NAME);
>         if (IS_ERR(i2s->reg_base)) {
>                 dev_err(dev, "iomap_region failed\n");
>
>
> base-commit: db2ddb87143519e20a95aa36c60b36107b736a58
> --
> This is an AI-generated patch subject to moderation.
> Reply with '#syz upstream' to Sign-off the patch as a human author
> and send it to the upstream kernel mailing lists.
> Reply with '#syz reject' to reject it ('#syz unreject' to undo).
>
> See https://goo.gle/syzbot-ai-patches for information about AI-generated patches.
> You can comment on the patch as usual, syzbot will try to address
> the comments and send a new version of the patch if necessary.
> syzbot engineers can be reached at [email protected].
>
> --
> You received this message because you are subscribed to the Google Groups "syzkaller-upstream-moderation" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
> To view this discussion visit https://groups.google.com/d/msgid/syzkaller-upstream-moderation/ceeaac79-e6f5-4a49-b72f-c3fda07d5d7c%40mail.kernel.org.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.