[PATCH RFC] ALSA: Validate MMIO BARs before mapping

0 views
Skip to first unread message

syzbot

unread,
9:19 AM (8 hours ago) 9:19 AM
to syzkaller-upst...@googlegroups.com, syz...@lists.linux.dev
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: syzbot+10cd2d...@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=10cd2d1efe8eeb604bee
Link: https://syzkaller.appspot.com/ai_job?id=dd4258ea-3be3-4977-b597-0fc0910b0f51
To: "Mark Brown" <bro...@kernel.org>
To: "Clemens Ladisch" <cle...@ladisch.de>
To: "Liam Girdwood" <lgir...@gmail.com>
To: <linux-...@vger.kernel.org>
To: <linux...@vger.kernel.org>
To: "Jaroslav Kysela" <pe...@perex.cz>
To: "Takashi Iwai" <ti...@suse.com>
To: "Binbin Zhou" <zhoub...@loongson.cn>
To: "Takashi Iwai" <ti...@suse.de>
Cc: "Chandra Mohan Sundar" <chandramoh...@gmail.com>
Cc: "Kai Vehmanen" <kai.ve...@linux.intel.com>
Cc: "Kees Cook" <ke...@kernel.org>
Cc: <linux-...@vger.kernel.org>
Cc: "Peter Ujfalusi" <peter.u...@linux.intel.com>
Cc: "Philipp Stanner" <pha...@kernel.org>
Cc: "Thomas Gleixner" <tg...@kernel.org>
Cc: =?utf-8?b?VXdlIEtsZWluZS1Lw7ZuaWcgKFRoZSBDYXBhYmxlIEh1Yik=?= <u.klein...@baylibre.com>
Cc: "Haotian Zhang" <vu...@iscas.ac.cn>

---
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 syzk...@googlegroups.com.

Aleksandr Nogikh

unread,
9:33 AM (8 hours ago) 9:33 AM
to syzbot, syzkaller-upst...@googlegroups.com, syz...@lists.linux.dev
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
> --
> 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 syzkaller-upstream-m...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/syzkaller-upstream-moderation/ceeaac79-e6f5-4a49-b72f-c3fda07d5d7c%40mail.kernel.org.
Reply all
Reply to author
Forward
0 new messages