In the Linux kernel, the following vulnerability has been resolved:
mm: do file ownership checks with the proper mount idmap
Ever since idmapped mounts were introduced, inode ownership checks (for
side-channel protection) in mincore() and madvise(MADV_PAGEOUT) were done
against the nop_mnt_idmap, which completely ignores the file's mount's
idmap. This results in odd edgecases like:
1) mount/bind-mount with an idmap userA:userB:1
2) userB runs an owner_or_capable() check on file that is owned by userA
on-disk/in-memory, but owned by userB after idmap translation
3) owner_or_capable() mysteriously fails as the correct idmap wasn't supplied
In the case of mincore/madvise MADV_PAGEOUT, this is usually benign,
because file_permission(file, MAY_WRITE) will probably succeed, as it uses
the proper idmap internally, but it does not need to be the case on e.g a
0444 file where even the owner itself doesn't have permissions to write to
it.
Since this is clearly not trivial to get right, introduce a
file_owner_or_capable() that can carry the correct semantics, and switch
the various users in mm to it.
The issue was found by manual code inspection & an off-list discussion
with Jan Kara.
In the Linux kernel, the following vulnerability has been resolved:
module: decompress: check return value of module_extend_max_pages()
module_extend_max_pages() calls kvrealloc() internally and returns
-ENOMEM on allocation failure. The return value is never checked.
If the initial allocation fails, info->pages remains NULL and
info->max_pages remains 0. Subsequent calls to module_get_next_page()
will attempt to dynamically grow the array by calling
module_extend_max_pages(info, 0) since info->used_pages is 0. This
results in kvrealloc(NULL, 0) returning ZERO_SIZE_PTR, which is treated
as a success, leading to a dereference of ZERO_SIZE_PTR and a kernel
oops.
Fix: add the missing error check after module_extend_max_pages() and
return immediately on failure. This matches the pattern used by every
other kvrealloc() caller in the module loading path.
[Sami: Corrected the analysis in the commit message.]
In the Linux kernel, the following vulnerability has been resolved:
fpga: dfl-afu: validate DMA mapping length in afu_dma_map_region()
afu_ioctl_dma_map() accepts a 64-bit length from userspace via
DFL_FPGA_PORT_DMA_MAP ioctl without an upper bound check. The value
is passed to afu_dma_pin_pages() where npages is derived as
length >> PAGE_SHIFT and passed to pin_user_pages_fast() which takes
int nr_pages, causing implicit truncation if length is very large.
Validate map.length at the ioctl entry point before calling
afu_dma_map_region(), rejecting values whose page count exceeds
INT_MAX.
In the Linux kernel, the following vulnerability has been resolved:
Input: mms114 - reject an oversized device packet size
mms114_interrupt() reads a packet of touch data from the device into a
fixed-size on-stack buffer
struct mms114_touch touch[MMS114_MAX_TOUCH];
which holds MMS114_MAX_TOUCH (10) events of MMS114_EVENT_SIZE (8) bytes,
i.e. 80 bytes. The length of the I2C read into it is taken verbatim from
the device:
packet_size = mms114_read_reg(data, MMS114_PACKET_SIZE);
if (packet_size <= 0)
goto out;
...
error = __mms114_read_reg(data, MMS114_INFORMATION, packet_size,
(u8 *)touch);
packet_size is a single device register byte (0x0F) and the only check
is the lower bound packet_size <= 0; it is never bounded against the
size of touch[]. A malfunctioning, malicious or counterfeit controller
(or an attacker tampering with the I2C bus) can report a packet_size of
up to 255, so __mms114_read_reg() writes up to 175 bytes past the end of
touch[] on the IRQ-thread stack: a stack out-of-bounds write that can
overwrite the stack canary, saved registers and the return address.
A well-formed device never reports more than the buffer holds, so reject
an oversized packet and drop the report, consistent with the handler's
other error paths, rather than reading past the buffer.
In the Linux kernel, the following vulnerability has been resolved:
NTB: epf: Avoid pci_iounmap() with offset when PEER_SPAD and CONFIG share BAR
When BAR_PEER_SPAD and BAR_CONFIG share one PCI BAR, the module teardown
path ends up calling pci_iounmap() on the same iomem with some offset,
which is unnecessary and triggers a kernel warning like the following:
Trying to vunmap() nonexistent vm area (0000000069a5ffe8)
WARNING: mm/vmalloc.c:3470 at vunmap+0x58/0x68, CPU#5: modprobe/2937
[...]
Call trace:
vunmap+0x58/0x68 (P)
iounmap+0x34/0x48
pci_iounmap+0x2c/0x40
ntb_epf_pci_remove+0x44/0x80 [ntb_hw_epf]
pci_device_remove+0x48/0xf8
device_remove+0x50/0x88
device_release_driver_internal+0x1c8/0x228
driver_detach+0x50/0xb0
bus_remove_driver+0x74/0x100
driver_unregister+0x34/0x68
pci_unregister_driver+0x34/0xa0
ntb_epf_pci_driver_exit+0x14/0xfe0 [ntb_hw_epf]
[...]
Fix it by unmapping only when PEER_SPAD and CONFIG use difference bars.
In the Linux kernel, the following vulnerability has been resolved:
power: reset: linkstation-poweroff: fix use-after-free in the linkstation_poweroff_init()
Move of_node_put(dn) after the of_match_node() call, which still needs
the node pointer. The node reference is correctly released after use.
In the Linux kernel, the following vulnerability has been resolved:
fpga: region: fix use-after-free in child_regions_with_firmware()
Move of_node_put(child_region) after the error print to avoid accessing
freed memory when pr_err() references child_region.
[ Yilun: Fix the Fixes tag ]
In the Linux kernel, the following vulnerability has been resolved:
MIPS: DEC: Prevent initial console buffer from landing in XKPHYS
In 64-bit configurations calling the initial console output handler from
a kernel thread other than the initial one will result in a situation
where the stack has been placed in the XKPHYS 64-bit memory segment and
consequently so has been the buffer allocated there that is used as the
argument corresponding to the `%s' output conversion specifier for the
firmware's printf() entry point.
This 64-bit address will then be truncated by 32-bit firmware, resulting
in an attempt to access the wrong memory location, which in turn will
cause all kinds of unpredictable behaviour, such as a kernel crash:
Console: colour dummy device 160x64
Calibrating delay loop... 49.36 BogoMIPS (lpj=192512)
pid_max: default: 32768 minimum: 301
CPU 0 Unable to handle kernel paging request at virtual address 000000000203bd00, epc == ffffffffbfc08364, ra == ffffffffbfc08800
Oops[#1]:
CPU: 0 PID: 0 Comm: swapper Not tainted 5.18.0-rc2-00254-gfb649bda6f56-dirty #121
$ 0 : 0000000000000000 0000000000000001 0000000000000023 ffffffff80684ba0
$ 4 : 000000000203bd00 ffffffffbfc0f3b4 ffffffffffffffff 0000000000000073
$ 8 : 0a303d7469000000 0000000000000000 0000000000000073 ffffffffbfc0f473
$12 : 0000000000000002 0000000000000000 ffffffff80684c1c 0000000000000000
$16 : 0000000000000000 ffffffff80596dc9 0000000000000000 ffffffffbfc09240
$20 : ffffffff80684c40 ffffffffbfc0f400 000000000000002d 000000000000002b
$24 : ffffffffffffffbf 000000000203bd00
$28 : ffffffff805f0000 ffffffff80684b58 0000000000000030 ffffffffbfc08800
Hi : 0000000000000000
Lo : 0000000000000aa8
epc : ffffffffbfc08364 0xffffffffbfc08364
ra : ffffffffbfc08800 0xffffffffbfc08800
Status: 140120e2 KX SX UX KERNEL EXL
Cause : 00000008 (ExcCode 02)
BadVA : 000000000203bd00
PrId : 00000430 (R4000SC)
Modules linked in:
Process swapper (pid: 0, threadinfo=(____ptrval____), task=(____ptrval____), tls=0000000000000000)
Stack : 0000000000000000 0000000000000000 0000000000000000 0000004d0000004d
80684cc0806a2a40 80596dc80000004d 8061000000000000 bfc0850c80684c38
0000000000000000 000000000203bd00 0000000000000000 0000000000000000
0000000000000000 00000000bfc0f3b4 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
0000002500000000 0000000000000000 0000000000000000 802c1a7400000000
0203bd0080596dc8 0203bd4d69000000 6c61632000000018 5f746567646e6172
6c616320625f6d6f 5f736e5f6d6f7266 206361323778302b 303d74696e726320
806a0a38806b0000 806a0a38806b0000 00000000806b0000 80683c58806b0000
...
Call Trace:
Code: a082ffff 03e00008 00601021 <80820000> 00001821 10400005 24840001 80820000 24630001
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Fatal exception in interrupt
KN04 V2.1k (PC: 0xa0026768, SP: 0x806848e8)
>>
In this case the pointer in $4 was truncated from 0x980000000203bd00 to
0x000000000203bd00.
This may happen when no final console driver has been enabled in the
configuration and consequently the initial console continues being used
late into bootstrap or with an upcoming change that will switch the zs
driver to use a platform device, which in turn will make the console
handover happen only after other kernel threads have already been
started.
Fix the issue by making the buffer static and initdata, and therefore
placed in the CKSEG0 32-bit compatibility segment, observing that the
console output handler is called with the console lock held, implying
no need for this code to be reentrant. Add an assertion to verify the
buffer actually has been placed in a compatibility segment.
In the Linux kernel, the following vulnerability has been resolved:
gpio: rockchip: teardown bugs and resource leaks
Address several teardown issues and resource leaks in the driver's remove
path and error handling:
1. Debounce clock reference leak: The debounce clock (bank->db_clk) is
obtained using of_clk_get() which increments the clock's reference
count, but clk_put() is never called. Register a devm action to
cleanly release it on unbind. Note that of_clk_get(..., 1) remains
necessary over devm_clk_get() because the DT binding does not define
clock-names, precluding name-based lookup.
2. Unregistered chained IRQ handler: The chained IRQ handler is not
disconnected in remove(). If a stray interrupt fires after the driver
is removed, the kernel attempts to execute a stale handler, leading
to a panic. Fix this by clearing the handler in remove().
3. IRQ domain leak: The linear IRQ domain and its generic chips are
allocated manually during probe but never removed. Remove the IRQ
domain during driver teardown to free the associated generic chips
and mappings.
[Bartosz: don't emit an error message on devres allocation failure]
In the Linux kernel, the following vulnerability has been resolved:
usb: gadget: net2280: Fix double free in probe error path
usb_initialize_gadget() installs gadget_release() as the release
callback for the embedded gadget device. The struct net2280 instance is
therefore released through gadget_release() when the gadget device's last
reference is dropped.
The probe error path calls net2280_remove(), which tears down the
partially initialized device and drops the gadget reference with
usb_put_gadget(). Calling kfree(dev) afterwards can free the same object
again.
Drop the explicit kfree() and let the gadget device release callback
handle the final free. This issue was found by a static analysis tool
I am developing.