In the Linux kernel, the following vulnerability has been resolved:
ALSA: us122l: Prevent write upgrades for read mappings
The hwdep mmap callback rejects read-buffer mappings that are initially
writable, but leaves VM_MAYWRITE set on mappings created with PROT_READ.
A process that can open the hwdep node O_RDWR can later use mprotect() to
make the mapping writable.
The read allocation begins with struct usb_stream. Its read_size member is
used by the fault handler to decide which pages belong to the read buffer.
The read VMA intentionally remains expandable because pcm_usb_stream uses
mremap() after reading that size. Changing read_size first can therefore
map and access pages beyond the allocation. The same member is also
consumed by usb_stream_free(), where changing it can make
free_pages_exact() release pages outside the allocation.
Clear VM_MAYWRITE for read-buffer mappings after rejecting an initially
writable VMA. This keeps the separate output-buffer mapping writable while
preventing later permission upgrades.
CVSS Vector: CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS Score: 7
AV:L - The bad data is written by a local process. It maps the us122l hwdep read buffer PROT_READ via usb_stream_hwdep_mmap(), upgrades it with mprotect() because VM_MAYWRITE was never cleared, and overwrites usb_stream.read_size. No remote protocol or USB packet carries the malicious value.
AC:H - The driver only binds, and only creates /dev/snd/hwCD, when a TASCAM US-122L/US-144 is attached. A local attacker can't produce that hardware without physical access. Once it is present, mmap, mprotect, a read_size overwrite and mremap are fully deterministic.
PR:L - The attacker needs an O_RDWR open of the hwdep node, which a normal user gets through audio group or seat uaccess ACLs. usb_stream_hwdep_open() and usb_stream_hwdep_ioctl() do no capability checks, and the stream already exists from probe.
UI:N - The attacker's own process does the open, mmap, mprotect, write to read_size, mremap and page faults. No other user has to act.
S:U - The result is corrupted kernel memory and local privilege escalation within the same kernel authority. No VM or hardware isolation boundary is crossed.
C:H - With an inflated read_size, usb_stream_hwdep_vm_fault() maps virt_to_page((char *)s + offset) for offsets past the alloc_pages_exact() buffer. Userspace can then directly read arbitrary adjacent kernel pages.
I:H - Those out-of-bounds pages are mapped writable into userspace, giving direct write access to kernel memory. In addition, usb_stream_free() calls free_pages_exact(s, read_size) with the tampered size, freeing pages that are still in use, a page-level use-after-free.
A:H - Writing to foreign kernel pages, or freeing the wrong pages through usb_stream_free() on SET_PARAMS re-init or disconnect, corrupts the page allocator and kernel data, which leads to an oops or panic.
| Attack Vector |
Local |
Scope |
Unchanged |
| Attack Complexity |
High |
Confidentiality Impact |
High |
| Privileges Required |
Low |
Integrity Impact |
High |
| User Interaction |
None |
Availability Impact |
High |
AV:L - The bad data is written by a local process. It maps the us122l hwdep read buffer PROT_READ via usb_stream_hwdep_mmap(), upgrades it with mprotect() because VM_MAYWRITE was never cleared, and overwrites usb_stream.read_size. No remote protocol or USB packet carries the malicious value.
AC:H - The driver only binds, and only creates /dev/snd/hwCD, when a TASCAM US-122L/US-144 is attached. A local attacker can't produce that hardware without physical access. Once it is present, mmap, mprotect, a read_size overwrite and mremap are fully deterministic.
PR:L - The attacker needs an O_RDWR open of the hwdep node, which a normal user gets through audio group or seat uaccess ACLs. usb_stream_hwdep_open() and usb_stream_hwdep_ioctl() do no capability checks, and the stream already exists from probe.
UI:N - The attacker's own process does the open, mmap, mprotect, write to read_size, mremap and page faults. No other user has to act.
S:U - The result is corrupted kernel memory and local privilege escalation within the same kernel authority. No VM or hardware isolation boundary is crossed.
C:H - With an inflated read_size, usb_stream_hwdep_vm_fault() maps virt_to_page((char *)s + offset) for offsets past the alloc_pages_exact() buffer. Userspace can then directly read arbitrary adjacent kernel pages.
I:H - Those out-of-bounds pages are mapped writable into userspace, giving direct write access to kernel memory. In addition, usb_stream_free() calls free_pages_exact(s, read_size) with the tampered size, freeing pages that are still in use, a page-level use-after-free.
A:H - Writing to foreign kernel pages, or freeing the wrong pages through usb_stream_free() on SET_PARAMS re-init or disconnect, corrupts the page allocator and kernel data, which leads to an oops or panic.
CVSS 3.1