summaryrefslogtreecommitdiff
path: root/drivers/media
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2026-02-24 21:51:16 +0300
committerSasha Levin <sashal@kernel.org>2026-03-12 14:09:34 +0300
commitcfd94642025e6f71c8f754bdec0800ee95e4f3dd (patch)
tree32b38b16dc3e37c1b48cc84541b5fcedd048abd5 /drivers/media
parent3acc627f235a903289a16753056dc63a0bb2758a (diff)
downloadlinux-cfd94642025e6f71c8f754bdec0800ee95e4f3dd.tar.xz
media: dvb-core: fix wrong reinitialization of ringbuffer on reopen
commit bfbc0b5b32a8f28ce284add619bf226716a59bc0 upstream. dvb_dvr_open() calls dvb_ringbuffer_init() when a new reader opens the DVR device. dvb_ringbuffer_init() calls init_waitqueue_head(), which reinitializes the waitqueue list head to empty. Since dmxdev->dvr_buffer.queue is a shared waitqueue (all opens of the same DVR device share it), this orphans any existing waitqueue entries from io_uring poll or epoll, leaving them with stale prev/next pointers while the list head is reset to {self, self}. The waitqueue and spinlock in dvr_buffer are already properly initialized once in dvb_dmxdev_init(). The open path only needs to reset the buffer data pointer, size, and read/write positions. Replace the dvb_ringbuffer_init() call in dvb_dvr_open() with direct assignment of data/size and a call to dvb_ringbuffer_reset(), which properly resets pread, pwrite, and error with correct memory ordering without touching the waitqueue or spinlock. Cc: stable@vger.kernel.org Fixes: 34731df288a5f ("V4L/DVB (3501): Dmxdev: use dvb_ringbuffer") Reported-by: syzbot+ab12f0c08dd7ab8d057c@syzkaller.appspotmail.com Tested-by: syzbot+ab12f0c08dd7ab8d057c@syzkaller.appspotmail.com Link: https://lore.kernel.org/all/698a26d3.050a0220.3b3015.007d.GAE@google.com/ Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/dvb-core/dmxdev.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c
index 8a9cca6da3e0..ab34be22cd1a 100644
--- a/drivers/media/dvb-core/dmxdev.c
+++ b/drivers/media/dvb-core/dmxdev.c
@@ -168,7 +168,9 @@ static int dvb_dvr_open(struct inode *inode, struct file *file)
mutex_unlock(&dmxdev->mutex);
return -ENOMEM;
}
- dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
+ dmxdev->dvr_buffer.data = mem;
+ dmxdev->dvr_buffer.size = DVR_BUFFER_SIZE;
+ dvb_ringbuffer_reset(&dmxdev->dvr_buffer);
if (dmxdev->may_do_mmap)
dvb_vb2_init(&dmxdev->dvr_vb2_ctx, "dvr",
file->f_flags & O_NONBLOCK);