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.