In the Linux kernel, the following vulnerability has been resolved:
media: verisilicon: rockchip: reject AV1 frames exceeding the tile capacity
rockchip_vpu981_av1_dec_set_tile_info() indexes the tile group entry
array by tile1 * tile_cols + tile0, reading up to tile_cols * tile_rows
entries, lays out one descriptor per tile in the AV1_MAX_TILES tile_info
buffer, and programs the real tile_cols / tile_rows into the hardware.
The tile group entry control is a dynamic array sized to the number of
entries userspace submitted, independent of tile_cols / tile_rows, so a
frame that claims more tiles than entries reads past the array. A frame
that claims more than AV1_MAX_TILES tiles also leaves the hardware
programmed for more tiles than the descriptor buffer holds.
Reject both in prepare_run(): tile_cols * tile_rows must not exceed the
submitted entry count or AV1_MAX_TILES. The entry count is read via
v4l2_ctrl_find() (ctrl->elems). This mirrors the bound the mediatek AV1
decoder already enforces.
CVSS Vector: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS Score: 7.8
AV:L - The malformed tile_cols/tile_rows and TILE_GROUP_ENTRY data are supplied by a local process through V4L2 request ioctls (VIDIOC_S_EXT_CTRLS + MEDIA_REQUEST_IOC_QUEUE) on the vpu981 /dev/videoN decoder, reaching rockchip_vpu981_av1_dec_run() -> set_tile_info(); no network protocol carries the input.
AC:L - validate_av1_frame() never bounds tile_cols/tile_rows (u8, up to 255), so setting tile_colstile_rows above 128 makes set_tile_info() deterministically write 16 bytes per tile past the 2KB AV1_TILE_INFO_SIZE buffer, with no race and no outside condition.
PR:L - No capability check guards the stateless decoder's controls or request queue; the attacker only needs open access to the /dev/videoN node, which desktop udev grants to the logged-in seat user (uaccess) or the video group, i.e. an ordinary local user.
UI:N - The attacker builds the AV1 frame and tile group entry controls and queues the decode request themselves; no other user has to act.
S:U - The corruption is of kernel memory adjacent to the tile_info coherent buffer, and the resulting impact stays within the kernel's own authority; no VM, IOMMU or sandbox boundary is crossed.
C:H - set_tile_info() reads group_entry[tile_id] past the dynamic TILE_GROUP_ENTRY array and width/height_in_sbs_minus_1[] past 64 entries; this out-of-bounds heap read is not strictly bounded to a few bytes, and the write primitive enables further disclosure.
I:H - The loop writes tile_colstile_rows*16 bytes (up to ~1MB) into a 2KB dma_alloc_coherent buffer, with attacker-controlled tile_offset/tile_size and tile width/height bytes, giving an out-of-bounds kernel memory write of attacker-controlled data and length.
A:H - A large overflow past the tile_info allocation corrupts adjacent kernel memory or faults on an unmapped guard page, causing a kernel oops or panic that the attacker can repeat at will.
| Attack Vector |
Local |
Scope |
Unchanged |
| Attack Complexity |
Low |
Confidentiality Impact |
High |
| Privileges Required |
Low |
Integrity Impact |
High |
| User Interaction |
None |
Availability Impact |
High |
AV:L - The malformed tile_cols/tile_rows and TILE_GROUP_ENTRY data are supplied by a local process through V4L2 request ioctls (VIDIOC_S_EXT_CTRLS + MEDIA_REQUEST_IOC_QUEUE) on the vpu981 /dev/videoN decoder, reaching rockchip_vpu981_av1_dec_run() -> set_tile_info(); no network protocol carries the input.
AC:L - validate_av1_frame() never bounds tile_cols/tile_rows (u8, up to 255), so setting tile_colstile_rows above 128 makes set_tile_info() deterministically write 16 bytes per tile past the 2KB AV1_TILE_INFO_SIZE buffer, with no race and no outside condition.
PR:L - No capability check guards the stateless decoder's controls or request queue; the attacker only needs open access to the /dev/videoN node, which desktop udev grants to the logged-in seat user (uaccess) or the video group, i.e. an ordinary local user.
UI:N - The attacker builds the AV1 frame and tile group entry controls and queues the decode request themselves; no other user has to act.
S:U - The corruption is of kernel memory adjacent to the tile_info coherent buffer, and the resulting impact stays within the kernel's own authority; no VM, IOMMU or sandbox boundary is crossed.
C:H - set_tile_info() reads group_entry[tile_id] past the dynamic TILE_GROUP_ENTRY array and width/height_in_sbs_minus_1[] past 64 entries; this out-of-bounds heap read is not strictly bounded to a few bytes, and the write primitive enables further disclosure.
I:H - The loop writes tile_colstile_rows*16 bytes (up to ~1MB) into a 2KB dma_alloc_coherent buffer, with attacker-controlled tile_offset/tile_size and tile width/height bytes, giving an out-of-bounds kernel memory write of attacker-controlled data and length.
A:H - A large overflow past the tile_info allocation corrupts adjacent kernel memory or faults on an unmapped guard page, causing a kernel oops or panic that the attacker can repeat at will.
CVSS 3.1