Security Vulnerabilities
- CVEs Published In May 2024
In the Linux kernel, the following vulnerability has been resolved:
bus: mhi: pci_generic: Fix possible use-after-free in mhi_pci_remove()
This driver's remove path calls del_timer(). However, that function
does not wait until the timer handler finishes. This means that the
timer handler may still be running after the driver's remove function
has finished, which would result in a use-after-free.
Fix by calling del_timer_sync(), which makes sure the timer handler
has finished, and unable to re-schedule itself.
In the Linux kernel, the following vulnerability has been resolved:
usb: misc: brcmstb-usb-pinmap: check return value after calling platform_get_resource()
It will cause null-ptr-deref if platform_get_resource() returns NULL,
we need check the return value.
In the Linux kernel, the following vulnerability has been resolved:
drm: Fix use-after-free read in drm_getunique()
There is a time-of-check-to-time-of-use error in drm_getunique() due
to retrieving file_priv->master prior to locking the device's master
mutex.
An example can be seen in the crash report of the use-after-free error
found by Syzbot:
https://syzkaller.appspot.com/bug?id=148d2f1dfac64af52ffd27b661981a540724f803
In the report, the master pointer was used after being freed. This is
because another process had acquired the device's master mutex in
drm_setmaster_ioctl(), then overwrote fpriv->master in
drm_new_set_master(). The old value of fpriv->master was subsequently
freed before the mutex was unlocked.
To fix this, we lock the device's master mutex before retrieving the
pointer from from fpriv->master. This patch passes the Syzbot
reproducer test.
In the Linux kernel, the following vulnerability has been resolved:
ALSA: seq: Fix race of snd_seq_timer_open()
The timer instance per queue is exclusive, and snd_seq_timer_open()
should have managed the concurrent accesses. It looks as if it's
checking the already existing timer instance at the beginning, but
it's not right, because there is no protection, hence any later
concurrent call of snd_seq_timer_open() may override the timer
instance easily. This may result in UAF, as the leftover timer
instance can keep running while the queue itself gets closed, as
spotted by syzkaller recently.
For avoiding the race, add a proper check at the assignment of
tmr->timeri again, and return -EBUSY if it's been already registered.
In the Linux kernel, the following vulnerability has been resolved:
spi: bcm2835: Fix out-of-bounds access with more than 4 slaves
Commit 571e31fa60b3 ("spi: bcm2835: Cache CS register value for
->prepare_message()") limited the number of slaves to 3 at compile-time.
The limitation was necessitated by a statically-sized array prepare_cs[]
in the driver private data which contains a per-slave register value.
The commit sought to enforce the limitation at run-time by setting the
controller's num_chipselect to 3: Slaves with a higher chipselect are
rejected by spi_add_device().
However the commit neglected that num_chipselect only limits the number
of *native* chipselects. If GPIO chipselects are specified in the
device tree for more than 3 slaves, num_chipselect is silently raised by
of_spi_get_gpio_numbers() and the result are out-of-bounds accesses to
the statically-sized array prepare_cs[].
As a bandaid fix which is backportable to stable, raise the number of
allowed slaves to 24 (which "ought to be enough for anybody"), enforce
the limitation on slave ->setup and revert num_chipselect to 3 (which is
the number of native chipselects supported by the controller).
An upcoming for-next commit will allow an arbitrary number of slaves.
In the Linux kernel, the following vulnerability has been resolved:
net:sfc: fix non-freed irq in legacy irq mode
SFC driver can be configured via modparam to work using MSI-X, MSI or
legacy IRQ interrupts. In the last one, the interrupt was not properly
released on module remove.
It was not freed because the flag irqs_hooked was not set during
initialization in the case of using legacy IRQ.
Example of (trimmed) trace during module remove without this fix:
remove_proc_entry: removing non-empty directory 'irq/125', leaking at least '0000:3b:00.1'
WARNING: CPU: 39 PID: 3658 at fs/proc/generic.c:715 remove_proc_entry+0x15c/0x170
...trimmed...
Call Trace:
unregister_irq_proc+0xe3/0x100
free_desc+0x29/0x70
irq_free_descs+0x47/0x70
mp_unmap_irq+0x58/0x60
acpi_unregister_gsi_ioapic+0x2a/0x40
acpi_pci_irq_disable+0x78/0xb0
pci_disable_device+0xd1/0x100
efx_pci_remove+0xa1/0x1e0 [sfc]
pci_device_remove+0x38/0xa0
__device_release_driver+0x177/0x230
driver_detach+0xcb/0x110
bus_remove_driver+0x58/0xd0
pci_unregister_driver+0x2a/0xb0
efx_exit_module+0x24/0xf40 [sfc]
__do_sys_delete_module.constprop.0+0x171/0x280
? exit_to_user_mode_prepare+0x83/0x1d0
do_syscall_64+0x3d/0x80
entry_SYSCALL_64_after_hwframe+0x44/0xae
RIP: 0033:0x7f9f9385800b
...trimmed...
In the Linux kernel, the following vulnerability has been resolved:
isdn: mISDN: netjet: Fix crash in nj_probe:
'nj_setup' in netjet.c might fail with -EIO and in this case
'card->irq' is initialized and is bigger than zero. A subsequent call to
'nj_release' will free the irq that has not been requested.
Fix this bug by deleting the previous assignment to 'card->irq' and just
keep the assignment before 'request_irq'.
The KASAN's log reveals it:
[ 3.354615 ] WARNING: CPU: 0 PID: 1 at kernel/irq/manage.c:1826
free_irq+0x100/0x480
[ 3.355112 ] Modules linked in:
[ 3.355310 ] CPU: 0 PID: 1 Comm: swapper/0 Not tainted
5.13.0-rc1-00144-g25a1298726e #13
[ 3.355816 ] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014
[ 3.356552 ] RIP: 0010:free_irq+0x100/0x480
[ 3.356820 ] Code: 6e 08 74 6f 4d 89 f4 e8 5e ac 09 00 4d 8b 74 24 18
4d 85 f6 75 e3 e8 4f ac 09 00 8b 75 c8 48 c7 c7 78 c1 2e 85 e8 e0 cf f5
ff <0f> 0b 48 8b 75 c0 4c 89 ff e8 72 33 0b 03 48 8b 43 40 4c 8b a0 80
[ 3.358012 ] RSP: 0000:ffffc90000017b48 EFLAGS: 00010082
[ 3.358357 ] RAX: 0000000000000000 RBX: ffff888104dc8000 RCX:
0000000000000000
[ 3.358814 ] RDX: ffff8881003c8000 RSI: ffffffff8124a9e6 RDI:
00000000ffffffff
[ 3.359272 ] RBP: ffffc90000017b88 R08: 0000000000000000 R09:
0000000000000000
[ 3.359732 ] R10: ffffc900000179f0 R11: 0000000000001d04 R12:
0000000000000000
[ 3.360195 ] R13: ffff888107dc6000 R14: ffff888107dc6928 R15:
ffff888104dc80a8
[ 3.360652 ] FS: 0000000000000000(0000) GS:ffff88817bc00000(0000)
knlGS:0000000000000000
[ 3.361170 ] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 3.361538 ] CR2: 0000000000000000 CR3: 000000000582e000 CR4:
00000000000006f0
[ 3.362003 ] DR0: 0000000000000000 DR1: 0000000000000000 DR2:
0000000000000000
[ 3.362175 ] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7:
0000000000000400
[ 3.362175 ] Call Trace:
[ 3.362175 ] nj_release+0x51/0x1e0
[ 3.362175 ] nj_probe+0x450/0x950
[ 3.362175 ] ? pci_device_remove+0x110/0x110
[ 3.362175 ] local_pci_probe+0x45/0xa0
[ 3.362175 ] pci_device_probe+0x12b/0x1d0
[ 3.362175 ] really_probe+0x2a9/0x610
[ 3.362175 ] driver_probe_device+0x90/0x1d0
[ 3.362175 ] ? mutex_lock_nested+0x1b/0x20
[ 3.362175 ] device_driver_attach+0x68/0x70
[ 3.362175 ] __driver_attach+0x124/0x1b0
[ 3.362175 ] ? device_driver_attach+0x70/0x70
[ 3.362175 ] bus_for_each_dev+0xbb/0x110
[ 3.362175 ] ? rdinit_setup+0x45/0x45
[ 3.362175 ] driver_attach+0x27/0x30
[ 3.362175 ] bus_add_driver+0x1eb/0x2a0
[ 3.362175 ] driver_register+0xa9/0x180
[ 3.362175 ] __pci_register_driver+0x82/0x90
[ 3.362175 ] ? w6692_init+0x38/0x38
[ 3.362175 ] nj_init+0x36/0x38
[ 3.362175 ] do_one_initcall+0x7f/0x3d0
[ 3.362175 ] ? rdinit_setup+0x45/0x45
[ 3.362175 ] ? rcu_read_lock_sched_held+0x4f/0x80
[ 3.362175 ] kernel_init_freeable+0x2aa/0x301
[ 3.362175 ] ? rest_init+0x2c0/0x2c0
[ 3.362175 ] kernel_init+0x18/0x190
[ 3.362175 ] ? rest_init+0x2c0/0x2c0
[ 3.362175 ] ? rest_init+0x2c0/0x2c0
[ 3.362175 ] ret_from_fork+0x1f/0x30
[ 3.362175 ] Kernel panic - not syncing: panic_on_warn set ...
[ 3.362175 ] CPU: 0 PID: 1 Comm: swapper/0 Not tainted
5.13.0-rc1-00144-g25a1298726e #13
[ 3.362175 ] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS
rel-1.12.0-59-gc9ba5276e321-prebuilt.qemu.org 04/01/2014
[ 3.362175 ] Call Trace:
[ 3.362175 ] dump_stack+0xba/0xf5
[ 3.362175 ] ? free_irq+0x100/0x480
[ 3.362175 ] panic+0x15a/0x3f2
[ 3.362175 ] ? __warn+0xf2/0x150
[ 3.362175 ] ? free_irq+0x100/0x480
[ 3.362175 ] __warn+0x108/0x150
[ 3.362175 ] ? free_irq+0x100/0x480
[ 3.362175 ] report_bug+0x119/0x1c0
[ 3.362175 ] handle_bug+0x3b/0x80
[ 3.362175 ] exc_invalid_op+0x18/0x70
[ 3.362175 ] asm_exc_invalid_op+0x12/0x20
[ 3.362175 ] RIP: 0010:free_irq+0x100
---truncated---
In the Linux kernel, the following vulnerability has been resolved:
bus: mhi: core: Validate channel ID when processing command completions
MHI reads the channel ID from the event ring element sent by the
device which can be any value between 0 and 255. In order to
prevent any out of bound accesses, add a check against the maximum
number of channels supported by the controller and those channels
not configured yet so as to skip processing of that event ring
element.
In the Linux kernel, the following vulnerability has been resolved:
driver core: auxiliary bus: Fix memory leak when driver_register() fail
If driver_register() returns with error we need to free the memory
allocated for auxdrv->driver.name before returning from
__auxiliary_driver_register()
In the Linux kernel, the following vulnerability has been resolved:
media: ngene: Fix out-of-bounds bug in ngene_command_config_free_buf()
Fix an 11-year old bug in ngene_command_config_free_buf() while
addressing the following warnings caught with -Warray-bounds:
arch/alpha/include/asm/string.h:22:16: warning: '__builtin_memcpy' offset [12, 16] from the object at 'com' is out of the bounds of referenced subobject 'config' with type 'unsigned char' at offset 10 [-Warray-bounds]
arch/x86/include/asm/string_32.h:182:25: warning: '__builtin_memcpy' offset [12, 16] from the object at 'com' is out of the bounds of referenced subobject 'config' with type 'unsigned char' at offset 10 [-Warray-bounds]
The problem is that the original code is trying to copy 6 bytes of
data into a one-byte size member _config_ of the wrong structue
FW_CONFIGURE_BUFFERS, in a single call to memcpy(). This causes a
legitimate compiler warning because memcpy() overruns the length
of &com.cmd.ConfigureBuffers.config. It seems that the right
structure is FW_CONFIGURE_FREE_BUFFERS, instead, because it contains
6 more members apart from the header _hdr_. Also, the name of
the function ngene_command_config_free_buf() suggests that the actual
intention is to ConfigureFreeBuffers, instead of ConfigureBuffers
(which takes place in the function ngene_command_config_buf(), above).
Fix this by enclosing those 6 members of struct FW_CONFIGURE_FREE_BUFFERS
into new struct config, and use &com.cmd.ConfigureFreeBuffers.config as
the destination address, instead of &com.cmd.ConfigureBuffers.config,
when calling memcpy().
This also helps with the ongoing efforts to globally enable
-Warray-bounds and get us closer to being able to tighten the
FORTIFY_SOURCE routines on memcpy().