Thread (4 messages) 4 messages, 3 authors, 25d ago

Re: [PATCH v2] module: decompress: check return value of module_extend_max_pages()

From: Sami Tolvanen <samitolvanen@google.com>
Date: 2026-05-19 21:23:35
Also in: lkml, stable

Hi Andrii,

On Mon, May 18, 2026 at 05:32:33PM +0300, Andrii Kuchmenko wrote:
module_extend_max_pages() calls kvrealloc() internally and returns
-ENOMEM on allocation failure. The return value is never checked.
We should definitely fix this, but I'm not sure the rest of the
commit message is entirely accurate.
The decompression loop then continues calling module_get_next_page(),
which writes struct page pointers into info->pages[]. When used_pages
reaches the stale max_pages value (not updated due to the failed
extend), a subsequent write to info->pages[used_pages++] goes out of
bounds into adjacent heap memory.

Adjacent slab objects in the same kmalloc cache (pipe_buffer,
seq_operations, cred) can be corrupted, potentially leading to local
privilege escalation on kernels without SLAB_VIRTUAL mitigation.
Looking at the code:

- struct load_info info is zero-initialized in init_module_from_file().

- If module_extend_max_pages() fails, info->pages remains NULL and
  info->max_pages and info->used_pages both remain 0.

- module_get_next_page() sees info->max_pages == info->used_pages
  immediately and calls module_extend_max_pages(info, 0).

- kvrealloc() is called with a size of 0 and it returns ZERO_SIZE_PTR.

- Because ZERO_SIZE_PTR != NULL, module_extend_max_pages() sets
  info->pages to ZERO_SIZE_PTR and returns 0.

- module_get_next_page() writes to info->pages[info->used_pages++],
  and the write to ZERO_SIZE_PTR results in an immediate oops.

This isn't great, but I do not see a potential for an out-of-bounds
write or slab corruption in this specific case. What am I missing?

Sami
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help