From c075292d261301d426c9265303250bc3bf333a49 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: May 19 2023 15:41:18 +0000 Subject: media: dvb-core: Fix kernel WARNING for blocking operation in wait_event*() (CVE-2023-31084 bsc#1210783). --- diff --git a/patches.suse/media-dvb-core-Fix-kernel-WARNING-for-blocking-opera.patch b/patches.suse/media-dvb-core-Fix-kernel-WARNING-for-blocking-opera.patch new file mode 100644 index 0000000..6725ab1 --- /dev/null +++ b/patches.suse/media-dvb-core-Fix-kernel-WARNING-for-blocking-opera.patch @@ -0,0 +1,60 @@ +From b8c75e4a1b325ea0a9433fa8834be97b5836b946 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Fri, 12 May 2023 16:18:00 +0100 +Subject: [PATCH] media: dvb-core: Fix kernel WARNING for blocking operation in wait_event*() +Git-commit: b8c75e4a1b325ea0a9433fa8834be97b5836b946 +Patch-mainline: v6.4-rc3 +References: CVE-2023-31084 bsc#1210783 + +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/20230512151800.1874-1-tiwai@suse.de +Reported-by: Yu Hao +Closes: https://nvd.nist.gov/vuln/detail/CVE-2023-31084 +Signed-off-by: Takashi Iwai +Signed-off-by: Mauro Carvalho Chehab + +--- + drivers/media/dvb-core/dvb_frontend.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +--- a/drivers/media/dvb-core/dvb_frontend.c ++++ b/drivers/media/dvb-core/dvb_frontend.c +@@ -293,14 +293,22 @@ static int dvb_frontend_get_event(struct + } + + if (events->eventw == events->eventr) { +- int ret; ++ struct wait_queue_entry wait; ++ int ret = 0; + + if (flags & O_NONBLOCK) + return -EWOULDBLOCK; + +- ret = wait_event_interruptible(events->wait_queue, +- dvb_frontend_test_event(fepriv, events)); +- ++ init_waitqueue_entry(&wait, current); ++ add_wait_queue(&events->wait_queue, &wait); ++ while (!dvb_frontend_test_event(fepriv, events)) { ++ wait_woken(&wait, TASK_INTERRUPTIBLE, 0); ++ if (signal_pending(current)) { ++ ret = -ERESTARTSYS; ++ break; ++ } ++ } ++ remove_wait_queue(&events->wait_queue, &wait); + if (ret < 0) + return ret; + } diff --git a/series.conf b/series.conf index d511927..ca38134 100644 --- a/series.conf +++ b/series.conf @@ -23125,6 +23125,7 @@ patches.suse/xfs-verify-buffer-contents-when-we-skip-log-replay.patch patches.suse/netfilter-nf_tables-deactivate-anonymous-set-from-pr.patch patches.suse/media-dvb-core-Fix-use-after-free-on-race-condition-.patch + patches.suse/media-dvb-core-Fix-kernel-WARNING-for-blocking-opera.patch ######################################################## # end of sorted patches