[PATCH] mm: kmemleak: start address align for scan_large_block

From: shuwang
Date: Wed Oct 11 2017 - 04:53:49 EST


From: Shu Wang <shuwang@xxxxxxxxxx>

If the start address is not ptr bytes aligned, it may cause false
positives when a pointer is split by MAX_SCAN_SIZE.

For example:
tcp_metrics_nl_family is in __ro_after_init area. On my PC, the
__start_ro_after_init is not ptr aligned, and
tcp_metrics_nl_family->attrbuf was break by MAX_SCAN_SIZE.

# cat /proc/kallsyms | grep __start_ro_after_init
ffffffff81afac8b R __start_ro_after_init

(gdb) p &tcp_metrics_nl_family->attrbuf
(struct nlattr ***) 0xffffffff81b12c88 <tcp_metrics_nl_family+72>

(gdb) p tcp_metrics_nl_family->attrbuf
(struct nlattr **) 0xffff88007b9d9400

scan_block(_start=0xffffffff81b11c8b, _end=0xffffffff81b12c8b, 0)
scan_block(_start=0xffffffff81b12c8b, _end=0xffffffff81b13c8b, 0)

unreferenced object 0xffff88007b9d9400 (size 128):
backtrace:
kmemleak_alloc+0x4a/0xa0
__kmalloc+0xec/0x220
genl_register_family.part.8+0x11c/0x5c0
genl_register_family+0x6f/0x90
tcp_metrics_init+0x33/0x47
tcp_init+0x27a/0x293
inet_init+0x176/0x28a
do_one_initcall+0x51/0x1b0

Signed-off-by: Shu Wang <shuwang@xxxxxxxxxx>
---
mm/kmemleak.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index 7780cd83a495..388b73e01fa4 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -1376,6 +1376,7 @@ static void scan_block(void *_start, void *_end,
static void scan_large_block(void *start, void *end)
{
void *next;
+ start = PTR_ALIGN(start, BYTES_PER_POINTER);

while (start < end) {
next = min(start + MAX_SCAN_SIZE, end);
--
2.13.5