mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Robin Murphy <robin.murphy@arm.com>
To: Jason Gunthorpe <jgg@ziepe.ca>
Cc: syzbot <syzbot+90c2d711b5218d10ce61@syzkaller.appspotmail.com>,
	baolu.lu@linux.intel.com, dwmw2@infradead.org,
	iommu@lists.linux.dev, joro@8bytes.org,
	linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com,
	will@kernel.org
Subject: Re: [syzbot] [iommu?] KASAN: slab-use-after-free Read in free_iova
Date: Tue, 11 Aug 2026 13:57:38 +0100	[thread overview]
Message-ID: <6f650cc2-b4fd-4305-b4d7-847ef935449a@arm.com> (raw)
In-Reply-To: <20260810173230.GQ200537@ziepe.ca>

On 10/08/2026 6:32 pm, Jason Gunthorpe wrote:
> On Mon, Aug 10, 2026 at 11:50:28AM +0100, Robin Murphy wrote:
>>> Freed by task 5327:
>>>    kasan_save_stack mm/kasan/common.c:57 [inline]
>>>    kasan_save_track+0x3e/0x80 mm/kasan/common.c:78
>>>    kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:584
>>>    poison_slab_object mm/kasan/common.c:253 [inline]
>>>    __kasan_slab_free+0x5c/0x80 mm/kasan/common.c:285
>>>    kasan_slab_free include/linux/kasan.h:235 [inline]
>>>    slab_free_hook mm/slub.c:2677 [inline]
>>>    slab_free mm/slub.c:6377 [inline]
>>>    kmem_cache_free+0x182/0x650 mm/slub.c:6504
>>>    free_iova_mem drivers/iommu/iova.c:237 [inline]
>>>    put_iova_domain+0xcc/0x100 drivers/iommu/iova.c:454
>>
>> ...except that right in between here we've called iommu_dma_free_fq() which
>> would have already invoked timer_delete_sync() and freed the queue itself.
>> Wut?
> 
> I've been feeding syzkaller riddles to the best AI I can get and it is
> surprisingly good.. So, for this it guesses:
> 
> ---
> timer_delete_sync() does stop already scheduled work, but it does not
> prevent a future mod_timer() from re-scheduling the now-deleted timer.
> 
> The probable sequence is:
> 
> 1. A DMA unmap queues an IOVA and sets fq_timer_on = 1 at dma-iommu.c
>     (line 243), but has not yet executed mod_timer().
> 
> 2. Concurrent PCI removal frees the device's default IOMMU
>     domain.
> 
> 3. iommu_dma_free_fq() calls timer_delete_sync() at dma-iommu.c (line
>     274). Because the timer is not pending at that instant, it returns.
> 
> 4. Teardown frees the flush queue and all IOVA-tree nodes through
>     put_iova_domain() (line 446).
> 
> 5. The unmap path resumes and executes mod_timer(), rearming a timer
>     embedded in the soon-to-be-freed DMA cookie.

But where would that unmap be? We're in a notifier near the end of 
device_del() here - the device is already very very dead, so anyone 
still using it for DMA doesn't simply have some subtle race. It 
seemingly couldn't even be in the device's driver, since pci_stop_dev() 
has also already unbound that, so it would presumably have to be an even 
more egregious subsystem-level UAF...

As I say though, the fact that it always appears to be an IOVA from 
reserve_iova() on the flush queue would seem to be the smoking gun 
pointing to this being well outside the scope of normal operation 
anyway. From one of the logs it seems that 00:01.0 belongs to lpc_ich, 
which is an MFD driver, so given the fact that it's an on-board chipset 
device, plus the tricks MFD plays to hang platform devices and their 
drivers off a PCI device, I could well imagine it has never expected to 
deal with removal very well, so I'm definitely leaning more toward some 
prior state corruption triggering this...

Cheers,
Robin.

> 6. fq_flush_timeout() later runs and calls free_iova_fast(). It
>     traverses the already-destroyed IOVA rbtree, producing the reported
>     UAF in private_find_iova() (line 275).
> ---
> 
> Which seems plausible to me.. So it is a bug in a driver allowing a
> dma API operation to be outstanding after it has been removed?
> 
> syzkaller console showed it did trigger a remove of a PCI function:
> 
> open("./sys/bus/pci/devices/0000:00:01.0/remove", O_WRONLY)
> write(fd, "1", 1)
> 
> But I couldn't guess what device that was, if someone from syzkaller
> land can clarify what they have plugged in there it might help.
> 
> The AI guessed on a GCE VM it was a display adaptor, but I don't see
> how it could know that.
> 
> It would be a nice improvement to the CONFIG DMA DEBUGGING to keep
> track of the driver bound state and blow up directly on all these
> forbidden combinations.
> 
> Jason


  parent reply	other threads:[~2026-08-11 12:57 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-09 23:44 syzbot
2026-08-10 10:50 ` Robin Murphy
2026-08-10 17:32   ` Jason Gunthorpe
2026-08-11  9:48     ` Will Deacon
2026-08-11 13:49       ` Jason Gunthorpe
2026-08-11 12:57     ` Robin Murphy [this message]
2026-08-11 13:11       ` Jason Gunthorpe
2026-08-13 16:59         ` Robin Murphy
2026-08-13 17:09           ` Jason Gunthorpe

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=6f650cc2-b4fd-4305-b4d7-847ef935449a@arm.com \
    --to=robin.murphy@arm.com \
    --cc=baolu.lu@linux.intel.com \
    --cc=dwmw2@infradead.org \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@ziepe.ca \
    --cc=joro@8bytes.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=syzbot+90c2d711b5218d10ce61@syzkaller.appspotmail.com \
    --cc=syzkaller-bugs@googlegroups.com \
    --cc=will@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

all inboxes | Powered by JetHome®