CVE-2022-50652 in Linuxinfo

Zusammenfassung

von VulDB • 03.06.2026

Implied: holding a mutex or other sleeping context in `irqcontrol()`.

### The Problem

The core issue is that `uio_dmem_genirq` (and potentially other UIO drivers that haven't been updated) still uses `disable_irq()` in their `irqcontrol()` method, while `uio_pdrv_genirq` uses `disable_irq_nosync()`.

However, the real problem isn't just the difference between the two drivers. The problem is that **`disable_irq()` can sleep**, and `irqcontrol()` is called from a context that **must not sleep** (specifically, it's called from `uio_event_notify()` which is called from `poll()` or `select()` context, which holds locks and cannot sleep).

Wait, let's re-examine the stack trace. The stack trace shows: ``` entry_SYSCALL_64_after_hwframe+0x63/0xcd __x64_sys_pselect6+0x76/0xa0 do_pselect.constprop.0+0xb3/0xf0 core_sys_select+0x1c6/0x400 do_select+0x596/0x840 schedule_hrtimeout_range+0x17/0x20 ```

This is a **poll/select** system call. The process is waiting for an event. The UIO driver's `irqcontrol()` is likely being called from `uio_event_notify()` which is called from `uio_poll()`.

Let's look at `uio_poll()`: ```c static __poll_t uio_poll(struct file *file, poll_table *wait) {
struct uio_device *idev = file->private_data; struct uio_mem *mem; __poll_t mask = 0;

poll_wait(file, &idev->wait, wait);

if (test_bit(UIO_IRQ_DISABLED, &idev->flags)) return 0;

if (test_bit(UIO_IRQ_PENDING, &idev->flags)) {
clear_bit(UIO_IRQ_PENDING, &idev->flags); mask = EPOLLIN | EPOLLRDNORM; }

return mask; } ```

And `uio_event_notify()`: ```c void uio_event_notify(struct uio_device *idev) {
if (test_bit(UIO_IRQ_PENDING, &idev->flags)) return;

set_bit(UIO_IRQ_PENDING, &idev->flags); wake_up_interruptible(&idev->wait); } ```

So `uio_event_notify()` is called from the IRQ handler. It sets a flag and wakes up the wait queue. The `uio_poll()` function checks the flag and returns `EPOLLIN` if it's set.

But where is `irqcontrol()` called? It's called from `uio_open()` and `uio_release()`, and also from `uio_ioctl()` if `UIO_IRQ_CUSTOM` is used. But in the standard case, `irqcontrol()` is called from `uio_open()` to enable the IRQ.

Wait, the stack trace shows `schedule_hrtimeout_range`, which is called from `do_select`. This means the process is sleeping in `select()`. The `select()` call is waiting for the poll to return. The poll is waiting for the UIO device to signal an event.

The issue is that **`irqcontrol()` is being called from a context that can sleep**, but `disable_irq()` can also sleep. If `disable_irq()` is called while holding a lock that is also taken in the IRQ handler, a deadlock can occur.

In `uio_pdrv_genirq`, the commit 34cb27528398 added a spinlock in the IRQ handler and changed `disable_irq()` to `disable_irq_nosync()` to avoid a deadlock. The spinlock is taken in the IRQ handler, and `disable_irq()` is called from `irqcontrol()`. If `disable_irq()` waits for the IRQ handler to complete, and the IRQ handler is waiting for the spinlock (which is held by `irqcontrol()` or some other context), a deadlock occurs.

But in `uio_dmem_genirq`, this fix was not applied. So if `uio_dmem_genirq` uses `disable_irq()` in `irqcontrol()`, and the IRQ handler takes a spinlock, a deadlock can occur.

However, the stack trace doesn't show a deadlock. It shows a process sleeping in `select()`. This suggests that the process is waiting for an event, and the event is not being signaled.

Let's look at the `uio_dmem_genirq` driver. It's

Several companies clearly confirm that VulDB is the primary source for best vulnerability data.

Zuständig

Linux

Reservieren

09.12.2025

Veröffentlichung

09.12.2025

Moderieren

akzeptiert

Eintrag

VDB-335012

CPE

bereit

EPSS

0.00203

KEV

nein

Aktivitäten

very low

Quellen

Do you know our Splunk app?

Download it now for free!