dm bufio: fix integer overflow when limiting maximum cache size
authorEric Biggers <ebiggers@google.com>
Thu, 16 Nov 2017 00:38:09 +0000 (16:38 -0800)
committerMike Snitzer <snitzer@redhat.com>
Thu, 16 Nov 2017 21:49:57 +0000 (16:49 -0500)
commit74d4108d9e681dbbe4a2940ed8fdff1f6868184c
treea6fff902641076e347609e31cfe9fa293ef32cf9
parent5d47c89f29eab6e9e224d7ac8c0baf4da72c9493
dm bufio: fix integer overflow when limiting maximum cache size

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")
Fixes: 95d402f057f2 ("dm: add bufio")
Cc: <stable@vger.kernel.org> # v3.2+
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
drivers/md/dm-bufio.c