Patch "dm bufio: fix integer overflow when limiting maximum cache size" has been added to the 4.9-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
dm bufio: fix integer overflow when limiting maximum cache size
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
dm-bufio-fix-integer-overflow-when-limiting-maximum-cache-size.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
74d4108d9e681dbbe4a2940ed8fdff1f6868184cMon Sep 17 00:00:00 2001
From: Eric Biggers <[email protected]>
Date: Wed, 15 Nov 2017 16:38:09 -0800
Subject: dm bufio: fix integer overflow when limiting maximum cache size
From: Eric Biggers <[email protected]>
commit 74d4108d9e681dbbe4a2940ed8fdff1f6868184c upstream.
The default max_cache_size_bytes for dm-bufio is meant to be the lesser of 25% of the size of the vmalloc area and 2% of the size of lowmem. However, on 32-bit systems the intermediate result in the expression
(VMALLOC_END - VMALLOC_START) * DM_BUFIO_VMALLOC_PERCENT / 100
overflows, causing the wrong result to be computed. For example, on a 32-bit system where the vmalloc area is 520093696 bytes, the result is 1174405 rather than the expected 130023424, which makes the maximum cache size much too small (far less than 2% of lowmem). This causes severe performance problems for dm-verity users on affected systems.
Fix this by using mult_frac() to correctly multiply by a percentage. Do this for all places in dm-bufio that multiply by a percentage. Also replace (VMALLOC_END - VMALLOC_START) with VMALLOC_TOTAL, which contrary to the comment is now defined in include/linux/vmalloc.h.
Depends-on: 9993bc635 ("sched/x86: Fix overflow in cyc2ns_offset")
--- drivers/md/dm-bufio.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-)
drivers/md/dm-bufio.c +6 -9
@@ -937,7 +937,8 @@ static void __get_memory_limit(struct dm buffers = c->minimum_buffers; *limit_buffers = buffers; - *threshold_buffers = buffers *DM_BUFIO_WRITEBACK_PERCENT /100 ; + *threshold_buffers =mult_frac (buffers, +DM_BUFIO_WRITEBACK_PERCENT ,100 ); }/*
@@ -1856,19 +1857,15 @@ static int __init dm_bufio_init(void)memset (&dm_bufio_caches,0 ,sizeof dm_bufio_caches);memset (&dm_bufio_cache_names,0 ,sizeof dm_bufio_cache_names); - mem = (__u64)((totalram_pages - totalhigh_pages) * -DM_BUFIO_MEMORY_PERCENT /100 ) <<PAGE_SHIFT ; + mem = (__u64 )mult_frac (totalram_pages - totalhigh_pages, +DM_BUFIO_MEMORY_PERCENT ,100 ) <<PAGE_SHIFT ;if (mem >ULONG_MAX ) mem =ULONG_MAX ;#ifdef CONFIG_MMU -/* -* Get the size of vmalloc space the same way as VMALLOC_TOTAL -* in fs/proc/internal.h -*/ -if (mem > (VMALLOC_END -VMALLOC_START ) *DM_BUFIO_VMALLOC_PERCENT /100 ) - mem = (VMALLOC_END -VMALLOC_START ) *DM_BUFIO_VMALLOC_PERCENT /100 ; +if (mem >mult_frac (VMALLOC_TOTAL ,DM_BUFIO_VMALLOC_PERCENT ,100 )) + mem =mult_frac (VMALLOC_TOTAL ,DM_BUFIO_VMALLOC_PERCENT ,100 );#endif dm_bufio_default_cache_size = mem;
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/lib-mpi-call-cond_resched-from-mpi_powm-loop.patch queue-4.9/dm-bufio-fix-integer-overflow-when-limiting-maximum-cache-size.patch