* [PATCH v2] mm/vmalloc: reject overflowing vm_map_ram page counts
@ 2026-10-23 6:43 Shubhang Kaushik (Ampere)
2026-10-30 3:55 ` Andrew Morton
2026-10-30 6:23 ` Dev Jain
0 siblings, 2 replies; 3+ messages in thread
From: Shubhang Kaushik (Ampere) @ 2026-10-23 6:43 UTC (permalink / raw)
To: Andrew Morton, Uladzislau Rezki, Nicholas Piggin,
Shubhang Kaushik, Christoph Lameter (Ampere)
Cc: linux-mm, linux-kernel, stable, Shubhang Kaushik (Ampere)
vm_map_ram() accepts a page count and must either map that many pages or
fail. It currently converts the count to a byte size with:
(unsigned long)count << PAGE_SHIFT
On 32-bit kernels, this conversion overflows when count is greater than
ULONG_MAX >> PAGE_SHIFT. vm_map_ram() then allocates and maps only the
wrapped byte size, but returns a non-NULL address to its caller.
For example, with 4 KiB pages, a count of 1048577 wraps to PAGE_SIZE.
vm_map_ram() therefore returns a mapping containing one page instead of
the requested 1048577 pages.
If a caller uses the successful result as a mapping of all requested
pages, it can access beyond the allocated mapping. Such an access can
fault. If the accessed virtual address is occupied by another vmalloc
mapping, it can instead access and corrupt unrelated kernel memory. In a
userspace-reachable call path, this can result in a failed operation, a
kernel oops or panic, or the effects of corrupted kernel data.
Return NULL before allocating or mapping anything when count * PAGE_SIZE
cannot be represented in an unsigned long.
Fixes: db64fe02258f ("mm: rewrite vmap layer")
Cc: stable@vger.kernel.org
Signed-off-by: Shubhang Kaushik (Ampere) <sh@gentwo.org>
---
Changes in v2:
- Use check_mul_overflow() to validate the page-count-to-byte conversion.
- Describe the short-mapping failure mode and its worst-case effects.
Link to v1: https://lore.kernel.org/r/20261022-vmalloc-reject-overflow-v1-1-5fde0042ffb9@gentwo.org
---
mm/vmalloc.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index bea9f76ed7e74247d4ce919250c2f02dd5c36483..8a056e424a4f2c037c10f736002839014f1f57dc 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3083,10 +3083,13 @@ EXPORT_SYMBOL(vm_unmap_ram);
*/
void *vm_map_ram(struct page **pages, unsigned int count, int node)
{
- unsigned long size = (unsigned long)count << PAGE_SHIFT;
+ unsigned long size;
unsigned long addr;
void *mem;
+ if (check_mul_overflow((unsigned long)count, PAGE_SIZE, &size))
+ return NULL;
+
if (likely(count <= VMAP_MAX_ALLOC)) {
mem = vb_alloc(size, GFP_KERNEL);
if (IS_ERR(mem))
---
base-commit: 734bef548a96e8774d6eef5dfa2026c6edc4e80b
change-id: 20261022-vmalloc-reject-overflow-e532c556f3fa
Best regards,
--
Shubhang Kaushik (Ampere) <sh@gentwo.org>
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH v2] mm/vmalloc: reject overflowing vm_map_ram page counts
2026-10-23 6:43 [PATCH v2] mm/vmalloc: reject overflowing vm_map_ram page counts Shubhang Kaushik (Ampere)
@ 2026-10-30 3:55 ` Andrew Morton
2026-10-30 6:23 ` Dev Jain
1 sibling, 0 replies; 3+ messages in thread
From: Andrew Morton @ 2026-10-30 3:55 UTC (permalink / raw)
To: Shubhang Kaushik (Ampere)
Cc: Uladzislau Rezki, Nicholas Piggin, Shubhang Kaushik,
Christoph Lameter (Ampere),
linux-mm, linux-kernel, stable, Dev Jain, Anshuman Khandual
On Thu, 22 Oct 2026 23:43:47 -0700 "Shubhang Kaushik (Ampere)" <sh@gentwo.org> wrote:
> vm_map_ram() accepts a page count and must either map that many pages or
> fail. It currently converts the count to a byte size with:
>
> (unsigned long)count << PAGE_SHIFT
>
> On 32-bit kernels, this conversion overflows when count is greater than
> ULONG_MAX >> PAGE_SHIFT. vm_map_ram() then allocates and maps only the
> wrapped byte size, but returns a non-NULL address to its caller.
>
> For example, with 4 KiB pages, a count of 1048577 wraps to PAGE_SIZE.
> vm_map_ram() therefore returns a mapping containing one page instead of
> the requested 1048577 pages.
>
> If a caller uses the successful result as a mapping of all requested
> pages, it can access beyond the allocated mapping. Such an access can
> fault. If the accessed virtual address is occupied by another vmalloc
> mapping, it can instead access and corrupt unrelated kernel memory. In a
> userspace-reachable call path, this can result in a failed operation, a
> kernel oops or panic, or the effects of corrupted kernel data.
>
> Return NULL before allocating or mapping anything when count * PAGE_SIZE
> cannot be represented in an unsigned long.
Thanks. Let's cc the developers who commented on the v1 patch.
> Fixes: db64fe02258f ("mm: rewrite vmap layer")
> Cc: stable@vger.kernel.org
> Signed-off-by: Shubhang Kaushik (Ampere) <sh@gentwo.org>
> ---
> Changes in v2:
> - Use check_mul_overflow() to validate the page-count-to-byte conversion.
> - Describe the short-mapping failure mode and its worst-case effects.
>
> Link to v1: https://lore.kernel.org/r/20261022-vmalloc-reject-overflow-v1-1-5fde0042ffb9@gentwo.org
> ---
> mm/vmalloc.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index bea9f76ed7e74247d4ce919250c2f02dd5c36483..8a056e424a4f2c037c10f736002839014f1f57dc 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -3083,10 +3083,13 @@ EXPORT_SYMBOL(vm_unmap_ram);
> */
> void *vm_map_ram(struct page **pages, unsigned int count, int node)
> {
> - unsigned long size = (unsigned long)count << PAGE_SHIFT;
> + unsigned long size;
> unsigned long addr;
> void *mem;
>
> + if (check_mul_overflow((unsigned long)count, PAGE_SIZE, &size))
> + return NULL;
> +
> if (likely(count <= VMAP_MAX_ALLOC)) {
> mem = vb_alloc(size, GFP_KERNEL);
> if (IS_ERR(mem))
>
> ---
> base-commit: 734bef548a96e8774d6eef5dfa2026c6edc4e80b
> change-id: 20261022-vmalloc-reject-overflow-e532c556f3fa
>
> Best regards,
> --
> Shubhang Kaushik (Ampere) <sh@gentwo.org>
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH v2] mm/vmalloc: reject overflowing vm_map_ram page counts
2026-10-23 6:43 [PATCH v2] mm/vmalloc: reject overflowing vm_map_ram page counts Shubhang Kaushik (Ampere)
2026-10-30 3:55 ` Andrew Morton
@ 2026-10-30 6:23 ` Dev Jain
1 sibling, 0 replies; 3+ messages in thread
From: Dev Jain @ 2026-10-30 6:23 UTC (permalink / raw)
To: Shubhang Kaushik (Ampere),
Andrew Morton, Uladzislau Rezki, Nicholas Piggin,
Shubhang Kaushik, Christoph Lameter (Ampere)
Cc: linux-mm, linux-kernel, stable
On 23/10/26 12:13 pm, Shubhang Kaushik (Ampere) wrote:
> vm_map_ram() accepts a page count and must either map that many pages or
> fail. It currently converts the count to a byte size with:
>
> (unsigned long)count << PAGE_SHIFT
>
> On 32-bit kernels, this conversion overflows when count is greater than
> ULONG_MAX >> PAGE_SHIFT. vm_map_ram() then allocates and maps only the
> wrapped byte size, but returns a non-NULL address to its caller.
>
> For example, with 4 KiB pages, a count of 1048577 wraps to PAGE_SIZE.
> vm_map_ram() therefore returns a mapping containing one page instead of
> the requested 1048577 pages.
>
> If a caller uses the successful result as a mapping of all requested
> pages, it can access beyond the allocated mapping. Such an access can
> fault. If the accessed virtual address is occupied by another vmalloc
> mapping, it can instead access and corrupt unrelated kernel memory. In a
> userspace-reachable call path, this can result in a failed operation, a
> kernel oops or panic, or the effects of corrupted kernel data.
>
> Return NULL before allocating or mapping anything when count * PAGE_SIZE
> cannot be represented in an unsigned long.
>
> Fixes: db64fe02258f ("mm: rewrite vmap layer")
> Cc: stable@vger.kernel.org
> Signed-off-by: Shubhang Kaushik (Ampere) <sh@gentwo.org>
> ---
I don't have much knowledge about 32-bit stuff but upon some discussion with LLM
the problem seems legit, maybe just hard to reproduce. Also there are sufficient
users of vm_map_ram() to care about this:
Reviewed-by: Dev Jain <dev.jain@arm.com>
> Changes in v2:
> - Use check_mul_overflow() to validate the page-count-to-byte conversion.
> - Describe the short-mapping failure mode and its worst-case effects.
>
> Link to v1: https://lore.kernel.org/r/20261022-vmalloc-reject-overflow-v1-1-5fde0042ffb9@gentwo.org
> ---
> mm/vmalloc.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/mm/vmalloc.c b/mm/vmalloc.c
> index bea9f76ed7e74247d4ce919250c2f02dd5c36483..8a056e424a4f2c037c10f736002839014f1f57dc 100644
> --- a/mm/vmalloc.c
> +++ b/mm/vmalloc.c
> @@ -3083,10 +3083,13 @@ EXPORT_SYMBOL(vm_unmap_ram);
> */
> void *vm_map_ram(struct page **pages, unsigned int count, int node)
> {
> - unsigned long size = (unsigned long)count << PAGE_SHIFT;
> + unsigned long size;
> unsigned long addr;
> void *mem;
>
> + if (check_mul_overflow((unsigned long)count, PAGE_SIZE, &size))
> + return NULL;
> +
> if (likely(count <= VMAP_MAX_ALLOC)) {
> mem = vb_alloc(size, GFP_KERNEL);
> if (IS_ERR(mem))
>
> ---
> base-commit: 734bef548a96e8774d6eef5dfa2026c6edc4e80b
> change-id: 20261022-vmalloc-reject-overflow-e532c556f3fa
>
> Best regards,
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-30 6:23 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-23 6:43 [PATCH v2] mm/vmalloc: reject overflowing vm_map_ram page counts Shubhang Kaushik (Ampere)
2026-10-30 3:55 ` Andrew Morton
2026-10-30 6:23 ` Dev Jain
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®