Skip to content

Commit b8c75e4

Browse files
tiwaimchehab
authored andcommitted
media: dvb-core: Fix kernel WARNING for blocking operation in wait_event*()
Using a semaphore in the wait_event*() condition is no good idea. It hits a kernel WARN_ON() at prepare_to_wait_event() like: do not call blocking ops when !TASK_RUNNING; state=1 set at prepare_to_wait_event+0x6d/0x690 For avoiding the potential deadlock, rewrite to an open-coded loop instead. Unlike the loop in wait_event*(), this uses wait_woken() after the condition check, hence the task state stays consistent. CVE-2023-31084 was assigned to this bug. Link: https://lore.kernel.org/r/CA+UBctCu7fXn4q41O_3=id1+OdyQ85tZY1x+TkT-6OVBL6KAUw@mail.gmail.com/ Link: https://lore.kernel.org/linux-media/[email protected] Reported-by: Yu Hao <[email protected]> Closes: https://nvd.nist.gov/vuln/detail/CVE-2023-31084 Signed-off-by: Takashi Iwai <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 627bb52 commit b8c75e4

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

drivers/media/dvb-core/dvb_frontend.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -293,14 +293,22 @@ static int dvb_frontend_get_event(struct dvb_frontend *fe,
293293
}
294294

295295
if (events->eventw == events->eventr) {
296-
int ret;
296+
struct wait_queue_entry wait;
297+
int ret = 0;
297298

298299
if (flags & O_NONBLOCK)
299300
return -EWOULDBLOCK;
300301

301-
ret = wait_event_interruptible(events->wait_queue,
302-
dvb_frontend_test_event(fepriv, events));
303-
302+
init_waitqueue_entry(&wait, current);
303+
add_wait_queue(&events->wait_queue, &wait);
304+
while (!dvb_frontend_test_event(fepriv, events)) {
305+
wait_woken(&wait, TASK_INTERRUPTIBLE, 0);
306+
if (signal_pending(current)) {
307+
ret = -ERESTARTSYS;
308+
break;
309+
}
310+
}
311+
remove_wait_queue(&events->wait_queue, &wait);
304312
if (ret < 0)
305313
return ret;
306314
}

0 commit comments

Comments
 (0)