)]}'
{
  "commit": "2e43a19f66745fcaa3789c2eae7fa3d2a95ac639",
  "tree": "cca1d091964f61edb59023b2fbc26a651a9337ff",
  "parents": [
    "05f7e89ab9731565d8a62e3b5d1ec206485eeb0b"
  ],
  "author": {
    "name": "Jens Axboe",
    "email": "axboe@kernel.dk",
    "time": "Mon Feb 09 13:37:31 2026 -0700"
  },
  "committer": {
    "name": "Jens Axboe",
    "email": "axboe@kernel.dk",
    "time": "Mon Feb 09 13:37:31 2026 -0700"
  },
  "message": "media: dvb-core: don\u0027t reinitialize dvr_buffer waitqueue on open\n\ndvb_dvr_open() calls dvb_ringbuffer_init() when a new reader opens the\nDVR device. dvb_ringbuffer_init() calls init_waitqueue_head(), which\nreinitializes the waitqueue list head to empty. Since\ndmxdev-\u003edvr_buffer.queue is a shared waitqueue (all opens of the same\nDVR device share it), this orphans any existing waitqueue entries from\nio_uring poll or epoll, leaving them with stale prev/next pointers\nwhile the list head is reset to {self, self}.\n\nA straightforward way to trigger this:\n\n1. Open /dev/dvb/adapter0/dvr0 with O_ACCMODE\u003d3 (an atypical flag\n   combination that skips the need_ringbuffer path in dvb_dvr_open,\n   so the ringbuffer is not initialized, but dvbdev-\u003eusers is\n   incremented).\n2. Set up io_uring and arm POLL_ADD on the DVB fd. This adds a\n   wait_queue_entry to dmxdev-\u003edvr_buffer.queue.\n3. Open /proc/self/fd/\u003cdvr_fd\u003e with O_RDONLY. This calls dvb_dvr_open\n   again, which enters the need_ringbuffer path and calls\n   dvb_ringbuffer_init() -\u003e init_waitqueue_head(), resetting the\n   waitqueue list head to empty. io_uring\u0027s poll entry is now\n   orphaned: its -\u003eprev still points to the list head, but the list\n   head\u0027s -\u003enext now points to itself.\n4. Process exits. io_uring task work runs io_poll_task_func() -\u003e\n   io_poll_remove_entries() -\u003e list_del_init() on the orphaned entry.\n   The list validation finds prev-\u003enext \u003d\u003d prev instead of the entry\n   being deleted, triggering the BUG:\n\n     list_del corruption. prev-\u003enext should be X, but was Y. (prev\u003dY)\n     kernel BUG at lib/list_debug.c:62!\n     RIP: __list_del_entry_valid_or_report\n     Call Trace:\n       io_poll_remove_entries\n       io_poll_task_func\n       io_handle_tw_list\n       tctx_task_work_run\n       tctx_task_work\n       task_work_run\n       do_exit\n\nThe waitqueue and spinlock in dvr_buffer are already properly\ninitialized once in dvb_dmxdev_init(). The open path only needs to\nreset the buffer data pointer, size, and read/write positions. Replace\nthe dvb_ringbuffer_init() call in dvb_dvr_open() with direct\nassignment of data/size and a call to dvb_ringbuffer_reset(), which\nproperly resets pread, pwrite, and error with correct memory ordering\nwithout touching the waitqueue or spinlock.\n\nReported-by: syzbot\nFixes: 1da177e4c3f4 (\"Linux-2.6.12-rc2\")\nSigned-off-by: Jens Axboe \u003caxboe@kernel.dk\u003e\n\nCo-Authored-By: Claude Opus 4.6 \u003cnoreply@anthropic.com\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "8c6f5aafda1d619a6f042f1f2abb1a7a158c5729",
      "old_mode": 33188,
      "old_path": "drivers/media/dvb-core/dmxdev.c",
      "new_id": "5cb46109d1ff6b01075cf0d1b9c789c4d34962a8",
      "new_mode": 33188,
      "new_path": "drivers/media/dvb-core/dmxdev.c"
    }
  ]
}
