* [syzbot] [media?] [dri?] kernel BUG in sync_timeline_signal
@ 2026-11-04 6:38 syzbot
2026-11-05 4:14 ` [PATCH] dma-buf/sw_sync: Optimize the retrieval of fence reference counts Edward Adam Davis
0 siblings, 1 reply; 3+ messages in thread
From: syzbot @ 2026-11-04 6:38 UTC (permalink / raw)
To: dri-devel, linux-kernel, linux-media, syzkaller-bugs
Hello,
syzbot found the following issue on:
HEAD commit: 6628e7d4c6b2 Linux 7.4-rc1
git tree: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
console output: https://syzkaller.appspot.com/x/log.txt?x=13fa63f1580000
kernel config: https://syzkaller.appspot.com/x/.config?x=1d2c97eac7d33533
dashboard link: https://syzkaller.appspot.com/bug?extid=cba1a1f459230395a076
compiler: gcc (Debian 14.2.0-19) 14.2.0, GNU ld (GNU Binutils for Debian) 2.44
C reproducer: https://syzkaller.appspot.com/x/repro.c?x=134d2959580000
AI-generated root cause summary:
In drivers/dma-buf/sw_sync.c, a race condition exists between dma_fence_put()
and sync_timeline_signal(). When the last reference to a sync_pt fence is
dropped, its refcount reaches 0 before dma_fence_release() ->
timeline_fence_release() acquires obj->lock to remove the sync_pt from
obj->pt_list. If sync_timeline_signal() runs concurrently under obj->lock, it
iterates obj->pt_list and calls dma_fence_get() on the fence whose refcount is
already 0, violating refcount invariants and causing a use-after-free / refcount
addition-on-0 kernel crash.
full analysis: https://syzkaller.appspot.com/x/ai_root_cause?x=cba1a1f459230395a076
IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+cba1a1f459230395a076@syzkaller.appspotmail.com
refcount_t: addition on 0; use-after-free.
------------[ cut here ]------------
kernel BUG at lib/refcount.c:34!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
CPU: 1 UID: 0 PID: 6018 Comm: syz-executor369 Tainted: G L syzkaller #0 PREEMPT(full)
Tainted: [L]=SOFTLOCKUP
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/15/2026
RIP: 0010:refcount_warn_saturate.cold+0x12/0x14 lib/refcount.c:34
Code: 89 ea be 01 00 00 00 48 c7 c7 40 c1 c3 90 e8 0a 5a 01 00 e9 72 e3 02 04 e8 c0 54 d7 00 48 c7 c7 a0 4a 81 8c e8 04 85 eb ff 90 <0f> 0b e8 ac 54 d7 00 48 c7 c7 40 4b 81 8c e8 f0 84 eb ff 90 0f 0b
RSP: 0018:ffffc90003e57cb8 EFLAGS: 00010086
RAX: 000000000000002a RBX: ffff88802d271570 RCX: 0000000000000000
RDX: 000000000000002a RSI: ffffffff81ebf219 RDI: fffff520007caf88
RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
R10: ffffc90003e57a7f R11: 0000000000000001 R12: 0000000000000000
R13: dffffc0000000000 R14: ffff88802d271300 R15: ffffc90003e57d18
FS: 00007f83e74d26c0(0000) GS:ffff88812257d000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f83e75a93c8 CR3: 00000000357c8000 CR4: 00000000003526f0
Call Trace:
<TASK>
__refcount_add include/linux/refcount.h:289 [inline]
__refcount_inc include/linux/refcount.h:366 [inline]
refcount_inc include/linux/refcount.h:383 [inline]
kref_get include/linux/kref.h:45 [inline]
dma_fence_get include/linux/dma-fence.h:323 [inline]
sync_timeline_signal+0x6d9/0x8a0 drivers/dma-buf/sw_sync.c:224
sw_sync_ioctl_inc drivers/dma-buf/sw_sync.c:405 [inline]
sw_sync_ioctl+0x7b4/0x13f0 drivers/dma-buf/sw_sync.c:470
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:597 [inline]
__se_sys_ioctl fs/ioctl.c:583 [inline]
__x64_sys_ioctl+0x18e/0x210 fs/ioctl.c:583
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f83e7507d5b
Code: 00 48 89 44 24 18 31 c0 48 8d 44 24 60 c7 04 24 10 00 00 00 48 89 44 24 08 48 8d 44 24 20 48 89 44 24 10 b8 10 00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 1c 48 8b 44 24 18 64 48 2b 04 25 28 00 00
RSP: 002b:00007f83e74d2100 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007f83e7507d5b
RDX: 00007f83e74d2170 RSI: 0000000040045701 RDI: 0000000000000003
RBP: 00000000000003d0 R08: 0000000000000000 R09: 00007f83e74d26c0
R10: 0000000000000008 R11: 0000000000000246 R12: 00007f83e74d2170
R13: 00000000000000f3 R14: 00007ffcce841440 R15: 00007ffcce841528
</TASK>
Modules linked in:
---[ end trace 0000000000000000 ]---
RIP: 0010:refcount_warn_saturate.cold+0x12/0x14 lib/refcount.c:34
Code: 89 ea be 01 00 00 00 48 c7 c7 40 c1 c3 90 e8 0a 5a 01 00 e9 72 e3 02 04 e8 c0 54 d7 00 48 c7 c7 a0 4a 81 8c e8 04 85 eb ff 90 <0f> 0b e8 ac 54 d7 00 48 c7 c7 40 4b 81 8c e8 f0 84 eb ff 90 0f 0b
RSP: 0018:ffffc90003e57cb8 EFLAGS: 00010086
RAX: 000000000000002a RBX: ffff88802d271570 RCX: 0000000000000000
RDX: 000000000000002a RSI: ffffffff81ebf219 RDI: fffff520007caf88
RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
R10: ffffc90003e57a7f R11: 0000000000000001 R12: 0000000000000000
R13: dffffc0000000000 R14: ffff88802d271300 R15: ffffc90003e57d18
FS: 00007f83e74d26c0(0000) GS:ffff88812257d000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f83e75a93c8 CR3: 00000000357c8000 CR4: 00000000003526f0
---
This report is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this issue. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
If the report is already addressed, let syzbot know by replying with:
#syz fix: exact-commit-title
If you want syzbot to run the reproducer, reply with:
#syz test: git://repo/address.git branch-or-commit-hash
If you attach or paste a git patch, syzbot will apply it before testing.
If you want to overwrite report's subsystems, reply with:
#syz set subsystems: new-subsystem
(See the list of subsystem names on the web dashboard)
If the report is a duplicate of another one, reply with:
#syz dup: exact-subject-of-another-report
If you want to undo deduplication, reply with:
#syz undup
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH] dma-buf/sw_sync: Optimize the retrieval of fence reference counts
2026-11-04 6:38 [syzbot] [media?] [dri?] kernel BUG in sync_timeline_signal syzbot
@ 2026-11-05 4:14 ` Edward Adam Davis
2026-11-05 9:53 ` Christian König
0 siblings, 1 reply; 3+ messages in thread
From: Edward Adam Davis @ 2026-11-05 4:14 UTC (permalink / raw)
To: syzbot+cba1a1f459230395a076
Cc: dri-devel, linux-kernel, linux-media, syzkaller-bugs,
sumit.semwal, christian.koenig, phasta, robin.clark
There is a race condition between closing a sync file and the SW_SYNC_IOC_INC
operation on a sync obj. When a fence is created via SW_SYNC_IOC_CREATE_FENCE,
its reference count is initialized to 1. When the sync file is closed, the
fence's reference count drops to 0. A race occurs if SW_SYNC_IOC_INC accesses
the fence whose ref count has already reached 0 before dma_fence_release()
calls timeline_fence_release() to erase the corresponding pt_tree node from
the sync object, potentially hitting:
refcount_t: addition on 0; use-after-free.
------------[ cut here ]------------
kernel BUG at lib/refcount.c:34!
Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
Call Trace:
kref_get include/linux/kref.h:45 [inline]
dma_fence_get include/linux/dma-fence.h:323 [inline]
sync_timeline_signal+0x6d9/0x8a0 drivers/dma-buf/sw_sync.c:224
sw_sync_ioctl_inc drivers/dma-buf/sw_sync.c:405 [inline]
sw_sync_ioctl+0x7b4/0x13f0 drivers/dma-buf/sw_sync.c:470
Use kref_get_unless_zero() to optimize dma_get_fence(), in order to avoid
acquiring an object with a reference count of 0.
Fixes: e531fdb5cd5e ("dma-buf/sw_sync: Avoid recursive lock during fence signal")
Reported-by: syzbot+cba1a1f459230395a076@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=cba1a1f459230395a076
Signed-off-by: Edward Adam Davis <eadavis@sina.com>
---
drivers/dma-buf/sw_sync.c | 3 ++-
include/linux/dma-fence.h | 5 +++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 8df20b0218a9..ad60ad5e5cd9 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -221,7 +221,8 @@ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
if (!timeline_fence_signaled(&pt->base))
break;
- dma_fence_get(&pt->base);
+ if (!dma_fence_get(&pt->base))
+ continue;
list_move_tail(&pt->link, &signalled);
rb_erase(&pt->node, &obj->pt_tree);
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
index dd07d128adc3..4d885c8e1d4f 100644
--- a/include/linux/dma-fence.h
+++ b/include/linux/dma-fence.h
@@ -320,8 +320,9 @@ static inline void dma_fence_put(struct dma_fence *fence)
static inline struct dma_fence *dma_fence_get(struct dma_fence *fence)
{
if (fence)
- kref_get(&fence->refcount);
- return fence;
+ if (kref_get_unless_zero(&fence->refcount))
+ return fence;
+ return NULL;
}
/**
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] dma-buf/sw_sync: Optimize the retrieval of fence reference counts
2026-11-05 4:14 ` [PATCH] dma-buf/sw_sync: Optimize the retrieval of fence reference counts Edward Adam Davis
@ 2026-11-05 9:53 ` Christian König
0 siblings, 0 replies; 3+ messages in thread
From: Christian König @ 2026-11-05 9:53 UTC (permalink / raw)
To: Edward Adam Davis, syzbot+cba1a1f459230395a076
Cc: dri-devel, linux-kernel, linux-media, syzkaller-bugs,
sumit.semwal, phasta, robin.clark
On 11/5/26 05:14, Edward Adam Davis wrote:
> There is a race condition between closing a sync file and the SW_SYNC_IOC_INC
> operation on a sync obj. When a fence is created via SW_SYNC_IOC_CREATE_FENCE,
> its reference count is initialized to 1. When the sync file is closed, the
> fence's reference count drops to 0. A race occurs if SW_SYNC_IOC_INC accesses
> the fence whose ref count has already reached 0 before dma_fence_release()
> calls timeline_fence_release() to erase the corresponding pt_tree node from
> the sync object, potentially hitting:
>
> refcount_t: addition on 0; use-after-free.
> ------------[ cut here ]------------
> kernel BUG at lib/refcount.c:34!
> Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI
> Call Trace:
> kref_get include/linux/kref.h:45 [inline]
> dma_fence_get include/linux/dma-fence.h:323 [inline]
> sync_timeline_signal+0x6d9/0x8a0 drivers/dma-buf/sw_sync.c:224
> sw_sync_ioctl_inc drivers/dma-buf/sw_sync.c:405 [inline]
> sw_sync_ioctl+0x7b4/0x13f0 drivers/dma-buf/sw_sync.c:470
>
> Use kref_get_unless_zero() to optimize dma_get_fence(), in order to avoid
> acquiring an object with a reference count of 0.
>
> Fixes: e531fdb5cd5e ("dma-buf/sw_sync: Avoid recursive lock during fence signal")
> Reported-by: syzbot+cba1a1f459230395a076@syzkaller.appspotmail.com
> Closes: https://syzkaller.appspot.com/bug?extid=cba1a1f459230395a076
> Signed-off-by: Edward Adam Davis <eadavis@sina.com>
> ---
> drivers/dma-buf/sw_sync.c | 3 ++-
> include/linux/dma-fence.h | 5 +++--
> 2 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
> index 8df20b0218a9..ad60ad5e5cd9 100644
> --- a/drivers/dma-buf/sw_sync.c
> +++ b/drivers/dma-buf/sw_sync.c
> @@ -221,7 +221,8 @@ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
> if (!timeline_fence_signaled(&pt->base))
> break;
>
> - dma_fence_get(&pt->base);
> + if (!dma_fence_get(&pt->base))
> + continue;
>
> list_move_tail(&pt->link, &signalled);
> rb_erase(&pt->node, &obj->pt_tree);
> diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
> index dd07d128adc3..4d885c8e1d4f 100644
> --- a/include/linux/dma-fence.h
> +++ b/include/linux/dma-fence.h
> @@ -320,8 +320,9 @@ static inline void dma_fence_put(struct dma_fence *fence)
> static inline struct dma_fence *dma_fence_get(struct dma_fence *fence)
> {
> if (fence)
> - kref_get(&fence->refcount);
> - return fence;
> + if (kref_get_unless_zero(&fence->refcount))
> + return fence;
> + return NULL;
Well we should have an automated filter function for nonsense like that.
First of all we have an dma_fence_get_rcu() function which uses kref_get_unless_zero() for this use case, so modifying the dma_fence_get() function is a clear no-go.
Then SW_SYNC is a testing functionality which can literally be used to intentionally crash the kernel with it! There is a massive warning and tainting the kernel when you try to use it.
So a race condition like that one here is completely negligible to this and so there is no justification for any stable backport whatsoever. We could of course fix it to improve the documentation purpose of the code, but that's about it.
And all of this is either obvious by reading the three lines of code below the ones you modified and/or the documentation of the component.
So please before you send out anything like that take a look around and thing for a few seconds if that really makes sense or is just a waste of time.
Regards,
Christian.
> }
>
> /**
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-11-05 9:53 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 6:38 [syzbot] [media?] [dri?] kernel BUG in sync_timeline_signal syzbot
2026-11-05 4:14 ` [PATCH] dma-buf/sw_sync: Optimize the retrieval of fence reference counts Edward Adam Davis
2026-11-05 9:53 ` Christian König
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox