mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Christian König" <christian.koenig@amd.com>
To: Jaeyoung Chung <jjy600901@snu.ac.kr>,
	dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org,
	linux-media@vger.kernel.org, sumit.semwal@linaro.org
Cc: linux-kernel@vger.kernel.org, eulgyukim@snu.ac.kr
Subject: Re: [BUG] WARNING: refcount bug in sync_timeline_signal
Date: Wed, 26 Aug 2026 10:34:09 +0200	[thread overview]
Message-ID: <0762ad09-12a9-4e44-9c8f-86c93f4925e7@amd.com> (raw)
In-Reply-To: <20260824155629.2370441-1-jjy600901@snu.ac.kr>

Hi Jaeyoung,

the SW_SYNC component is pretty much deprecated, only kept for user space unit testing and not maintained any more.

Background is that even if you fix all those known bugs you can still hard crash the Linux kernel with it. See the big warning in th KConfig and the kernel tainting when that component is enabled as well.

So if you have patches which fixes things I'm happy to take them, but nobody will investigate in bug reports on that component any more.

Regards,
Christian.

On 8/24/26 17:56, Jaeyoung Chung wrote:
> Hello,
> 
> We found a "WARNING: refcount bug in sync_timeline_signal" on Linux v7.2.
> The issue was found by our own race fuzzer. We have not analyzed the root cause,
> so we do not have a proposed fix to offer.
> 
> To reproduce the race reliably, we applied the delay patch below to the
> kernel and ran the C reproducer as root inside an x86_64 QEMU guest. The
> crash log we observed, the delay patch and the reproducer are all included
> below.
> 
> The following kernel config options are required to reproduce the issue:
>     CONFIG_SW_SYNC=y
>     CONFIG_SYNC_FILE=y
>     CONFIG_DMA_SHARED_BUFFER=y
>     CONFIG_DEBUG_FS=y
>     CONFIG_KASAN=y
> 
> We hope this report is useful. Please let us know if any further
> information would help.
> 
> Reported-by: Eulgyu Kim <eulgyukim@snu.ac.kr>
> Reported-by: Jaeyoung Chung <jjy600901@snu.ac.kr>
> 
> Kernel delay patch:
> ==================================================================
> diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
> index 8df20b0218a9..d30ce9d915ba 100644
> --- a/drivers/dma-buf/sw_sync.c
> +++ b/drivers/dma-buf/sw_sync.c
> @@ -8,6 +8,7 @@
>  #include <linux/file.h>
>  #include <linux/fs.h>
>  #include <linux/uaccess.h>
> +#include <linux/delay.h>
>  #include <linux/panic.h>
>  #include <linux/slab.h>
>  #include <linux/sync_file.h>
> @@ -215,6 +216,10 @@ static void sync_timeline_signal(struct sync_timeline *obj, unsigned int inc)
> 
>         spin_lock_irq(&obj->lock);
> 
> +       if (strncmp(current->comm, "syzrepro1", 9) == 0) {
> +               mdelay(50);
> +       }
> +
>         obj->value += inc;
> 
>         list_for_each_entry_safe(pt, next, &obj->pt_list, link) {
> ==================================================================
> 
> C reproducer:
> ==================================================================
> #define _GNU_SOURCE
> #include <errno.h>
> #include <fcntl.h>
> #include <pthread.h>
> #include <sched.h>
> #include <stdint.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/ioctl.h>
> #include <sys/mount.h>
> #include <sys/prctl.h>
> #include <sys/stat.h>
> #include <time.h>
> #include <unistd.h>
> 
> #define SYSCHK(x) ({ long __r = (long)(x); if (__r == -1L) { perror(#x); exit(1); } __r; })
> 
> #define SW_SYNC_IOC_CREATE_FENCE 0xc0285700u
> #define SW_SYNC_IOC_INC 0x40045701u
> #define SWSYNC "/sys/kernel/debug/sync/sw_sync"
> #define BIAS_US 2000
> 
> struct fence_data {
>         uint32_t value;
>         char name[32];
>         int32_t fence;
> };
> 
> static volatile int g_round, g_stop, g_tl_fd = -1, g_fence_fd = -1;
> static volatile int g_armed, g_done0, g_done1;
> 
> static void spin_us(long us)
> {
>         struct timespec a, b;
> 
>         clock_gettime(CLOCK_MONOTONIC, &a);
>         do {
>                 clock_gettime(CLOCK_MONOTONIC, &b);
>                 __asm__ __volatile__("pause" ::: "memory");
>         } while ((b.tv_sec - a.tv_sec) * 1000000L + (b.tv_nsec - a.tv_nsec) / 1000L < us);
> }
> 
> static void pin_cpu(int cpu)
> {
>         cpu_set_t set;
> 
>         CPU_ZERO(&set);
>         CPU_SET(cpu, &set);
>         sched_setaffinity(0, sizeof(set), &set);
> }
> 
> static int wait_round(int *last)
> {
>         while (g_round == *last && !g_stop)
>                 sched_yield();
>         if (g_stop)
>                 return 0;
>         *last = g_round;
>         return 1;
> }
> 
> /* T1: advances the timeline, signalling the pt */
> static void *thr_inc(void *a)
> {
>         unsigned int v = 1;
>         int last = 0;
> 
>         (void)a;
>         prctl(PR_SET_NAME, "syzrepro1", 0, 0, 0);
>         pin_cpu(0);
>         while (wait_round(&last)) {
>                 g_armed = 1;
>                 __sync_synchronize();
>                 ioctl(g_tl_fd, SW_SYNC_IOC_INC, &v);
>                 __sync_synchronize();
>                 g_done1 = 1;
>         }
>         return NULL;
> }
> 
> /* T0: closes the fence mid-signal, dropping the pt's last reference */
> static void *thr_close(void *a)
> {
>         int last = 0;
> 
>         (void)a;
>         prctl(PR_SET_NAME, "syzrepro0", 0, 0, 0);
>         pin_cpu(1);
>         while (wait_round(&last)) {
>                 while (!g_armed && !g_stop)
>                         __asm__ __volatile__("pause" ::: "memory");
>                 if (g_stop)
>                         break;
>                 spin_us(BIAS_US);
>                 close(g_fence_fd);
>                 __sync_synchronize();
>                 g_done0 = 1;
>         }
>         return NULL;
> }
> 
> static int open_sw_sync(void)
> {
>         int fd = open(SWSYNC, O_RDWR);
> 
>         if (fd >= 0 || errno != ENOENT)
>                 return fd;
>         mkdir("/sys/kernel/debug", 0755);
>         mount("debugfs", "/sys/kernel/debug", "debugfs", 0, NULL);
>         return open(SWSYNC, O_RDWR);
> }
> 
> int main(void)
> {
>         pthread_t t0, t1;
>         long i;
> 
>         close(SYSCHK(open_sw_sync()));
>         pthread_create(&t1, NULL, thr_inc, NULL);
>         pthread_create(&t0, NULL, thr_close, NULL);
> 
>         for (i = 0; i < 200 && !g_stop; i++) {
>                 struct fence_data d = { .value = 1, .name = "syzrepro_pt", .fence = -1 };
>                 int tl = SYSCHK(open_sw_sync()), w;
> 
>                 SYSCHK(ioctl(tl, SW_SYNC_IOC_CREATE_FENCE, &d));
>                 g_tl_fd = tl;
>                 g_fence_fd = d.fence;
>                 g_armed = g_done0 = g_done1 = 0;
>                 __sync_synchronize();
>                 g_round = i + 1;
> 
>                 for (w = 0; w < 5000 && !(g_done0 && g_done1); w++) {
>                         struct timespec ts = { 0, 1000000 };
> 
>                         nanosleep(&ts, NULL);
>                 }
>                 close(tl);
>         }
> 
>         g_stop = 1;
>         __sync_synchronize();
>         g_round++;
>         pthread_join(t1, NULL);
>         pthread_join(t0, NULL);
>         return 0;
> }
> ==================================================================
> 
> Crash log:
> ==================================================================
> refcount_t: addition on 0; use-after-free.
> WARNING: lib/refcount.c:25 at refcount_warn_saturate+0x76/0xd0 lib/refcount.c:25, CPU#0: syzrepro1/402
> Modules linked in:
> CPU: 0 UID: 0 PID: 402 Comm: syzrepro1 Tainted: G             L      7.2.0-dirty #2 PREEMPT
> Tainted: [L]=SOFTLOCKUP
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> RIP: 0010:refcount_warn_saturate+0x76/0xd0 lib/refcount.c:25
> Code: 3d ff e4 bb 04 67 48 0f b9 3a eb 4d 85 db 74 2f 83 fb 01 75 38 48 8d 3d f8 e4 bb 04 67 48 0f b9 3a eb 36 48 8d 3d fa e4 bb 04 <67> 48 0f b9 3a eb 28 48 8d 3d fc e4 bb 04 67 48 0f b9 3a eb 1a 48
> RSP: 0018:ffff88810cd47d68 EFLAGS: 00010046
> RAX: 0000000000000000 RBX: 0000000000000002 RCX: dffffc0000000000
> RDX: 0000000000000001 RSI: 0000000000000004 RDI: ffffffff9be2c840
> RBP: ffff888102a5dc40 R08: ffff888102a5d73b R09: 1ffff1102054bae7
> R10: dffffc0000000000 R11: ffffed102054bae8 R12: dffffc0000000000
> R13: ffff888102a5d740 R14: ffff888102a5d738 R15: ffff888102a5d738
> FS:  00007ae687b8f6c0(0000) GS:ffff88817d75f000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000578dd65f7e58 CR3: 000000010b72c000 CR4: 00000000000006f0
> Call Trace:
>  <TASK>
>  __refcount_add include/linux/refcount.h:-1 [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:317 [inline]
>  sync_timeline_signal+0x383/0x550 drivers/dma-buf/sw_sync.c:229
>  sw_sync_ioctl_inc drivers/dma-buf/sw_sync.c:410 [inline]
>  sw_sync_ioctl+0x140/0x980 drivers/dma-buf/sw_sync.c:475
>  vfs_ioctl fs/ioctl.c:51 [inline]
>  __do_sys_ioctl fs/ioctl.c:597 [inline]
>  __se_sys_ioctl+0xb6/0x100 fs/ioctl.c:583
>  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
>  do_syscall_64+0xf7/0x370 arch/x86/entry/syscall_64.c:94
>  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> RIP: 0033:0x7ae687c90d6b
> 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:00007ae687b8edd0 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
> RAX: ffffffffffffffda RBX: 00007ae687b8ee3c RCX: 00007ae687c90d6b
> RDX: 00007ae687b8ee38 RSI: 0000000040045701 RDI: 0000000000000003
> RBP: 0000000000000000 R08: 0000000000000000 R09: 00007ffcdb19abc7
> R10: 0000000000000000 R11: 0000000000000246 R12: ffffffffffffff80
> R13: 0000000000000000 R14: 00007ffcdb19aad0 R15: 00007ae68738f000
>  </TASK>
> ----------------
> Code disassembly (best guess):
>    0:   3d ff e4 bb 04          cmp    $0x4bbe4ff,%eax
>    5:   67 48 0f b9 3a          ud1    (%edx),%rdi
>    a:   eb 4d                   jmp    0x59
>    c:   85 db                   test   %ebx,%ebx
>    e:   74 2f                   je     0x3f
>   10:   83 fb 01                cmp    $0x1,%ebx
>   13:   75 38                   jne    0x4d
>   15:   48 8d 3d f8 e4 bb 04    lea    0x4bbe4f8(%rip),%rdi        # 0x4bbe514
>   1c:   67 48 0f b9 3a          ud1    (%edx),%rdi
>   21:   eb 36                   jmp    0x59
>   23:   48 8d 3d fa e4 bb 04    lea    0x4bbe4fa(%rip),%rdi        # 0x4bbe524
> * 2a:   67 48 0f b9 3a          ud1    (%edx),%rdi <-- trapping instruction
>   2f:   eb 28                   jmp    0x59
>   31:   48 8d 3d fc e4 bb 04    lea    0x4bbe4fc(%rip),%rdi        # 0x4bbe534
>   38:   67 48 0f b9 3a          ud1    (%edx),%rdi
>   3d:   eb 1a                   jmp    0x59
>   3f:   48                      rex.W
> ==================================================================
> 
> 


      reply	other threads:[~2026-08-26  8:34 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-24 15:56 Jaeyoung Chung
2026-08-26  8:34 ` Christian König [this message]

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=0762ad09-12a9-4e44-9c8f-86c93f4925e7@amd.com \
    --to=christian.koenig@amd.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=eulgyukim@snu.ac.kr \
    --cc=jjy600901@snu.ac.kr \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=sumit.semwal@linaro.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®