Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp709291pxv; Thu, 15 Jul 2021 14:06:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx+ynCap5Awh+26znWrU/0qwpExNJ4E1Y1AfAu/spIPEbFqwf9C6Vt2n0HvknDlLe49rkA9 X-Received: by 2002:a05:6402:30af:: with SMTP id df15mr9811418edb.19.1626383170870; Thu, 15 Jul 2021 14:06:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626383170; cv=none; d=google.com; s=arc-20160816; b=cOO3DWTR/wD4QtRohbwr+x+tNb+qVgxH/rK8SNQs8IUZk4zfpSE+s+7BFn9FuE+7nf tTpaea5jumfFodcU/P/kLPXTaiQJU+Rq39w4VMHrp6+SNjcNnbuuHj423Pmcih1gUuDf fKdvKBvFXOVVnXIQbTUkhNkhOQb73p6PAE9TjsOvQ1gOo937xZwxT4gnUhOgR4ebH3jS Oq6I6r983xbNGT86diMZpuJ7YTOAXET5N+DiI6w/xxKcsj2InWQWcDRNi4y+WNEtng5S mfNfdsZ8sBoxUHMa18mDgWMFATC15a/92BPQBK0UwYGqdO+OWgGLW1S9w7oEtVBjyY49 3+jw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=wzqbM7jf3ju3R5RPPWlc0TMnBITv6iusvf0vhUVYxL8=; b=uOWm/Roja6s4If4fYUDTOOV5HAncjBDd/2Y2cKRMFs1+vDKbgGjHREKsvb4RLvLJEu 9FPSxP5bTqvFufAiK90IV38YEZeVuObUt7+zGAGm9ED4TCY2vAeteHqnVpf6UVQnpFSt D26okWhfnbwp+qsvr6h244PNJRHGXIiv2bZU8qFl01prf5AbcidFMWODI8DeI0p67AZK ybeW8tiCpP2FW98MOI8HJmk+bWY9R60EVJzt9TOs8GxUwrWUwycojNfgQHXabzBzAbLO Sb4bvN0NXmn7M5l/Bg5m5jiw6Ji6b7gLxQBVaOx4E9tbpvQQNe/kYxp1L/rGVDce5BUV //9Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=fHcXc28p; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id jp3si8252037ejb.706.2021.07.15.14.05.44; Thu, 15 Jul 2021 14:06:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=fHcXc28p; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243019AbhGOTRQ (ORCPT + 99 others); Thu, 15 Jul 2021 15:17:16 -0400 Received: from mail.kernel.org ([198.145.29.99]:38428 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243067AbhGOTER (ORCPT ); Thu, 15 Jul 2021 15:04:17 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 25780613DC; Thu, 15 Jul 2021 18:59:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626375581; bh=0XRFg5hIq6dpQhf6aGNiDBR8wtXCngnhyGCW3ADbjSA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fHcXc28pMgQqUJlJuZ1HOdAjRYqyZdHzj/OQ3DZASPlkCWlwBhhu82YA0NJUnDO5Q rKQYhwxO05spB7ESR3ZfSfO8icjZNz1ix/PRyPetX+CZXj+STJIY39IVyGF67NDb10 KuflQlmr4qMLRh9TGGQ7mQlHlBlXi6Xi/pJX8fI8= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+5d895828587f49e7fe9b@syzkaller.appspotmail.com, Rustam Kovhaev , Daniel Borkmann , Dmitry Vyukov , Andrii Nakryiko , Sasha Levin Subject: [PATCH 5.12 147/242] bpf: Fix false positive kmemleak report in bpf_ringbuf_area_alloc() Date: Thu, 15 Jul 2021 20:38:29 +0200 Message-Id: <20210715182619.085854190@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210715182551.731989182@linuxfoundation.org> References: <20210715182551.731989182@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Rustam Kovhaev [ Upstream commit ccff81e1d028bbbf8573d3364a87542386c707bf ] kmemleak scans struct page, but it does not scan the page content. If we allocate some memory with kmalloc(), then allocate page with alloc_page(), and if we put kmalloc pointer somewhere inside that page, kmemleak will report kmalloc pointer as a false positive. We can instruct kmemleak to scan the memory area by calling kmemleak_alloc() and kmemleak_free(), but part of struct bpf_ringbuf is mmaped to user space, and if struct bpf_ringbuf changes we would have to revisit and review size argument in kmemleak_alloc(), because we do not want kmemleak to scan the user space memory. Let's simplify things and use kmemleak_not_leak() here. For posterity, also adding additional prior analysis from Andrii: I think either kmemleak or syzbot are misreporting this. I've added a bunch of printks around all allocations performed by BPF ringbuf. [...] On repro side I get these two warnings: [vmuser@archvm bpf]$ sudo ./repro BUG: memory leak unreferenced object 0xffff88810d538c00 (size 64): comm "repro", pid 2140, jiffies 4294692933 (age 14.540s) hex dump (first 32 bytes): 00 af 19 04 00 ea ff ff c0 ae 19 04 00 ea ff ff ................ 80 ae 19 04 00 ea ff ff c0 29 2e 04 00 ea ff ff .........)...... backtrace: [<0000000077bfbfbd>] __bpf_map_area_alloc+0x31/0xc0 [<00000000587fa522>] ringbuf_map_alloc.cold.4+0x48/0x218 [<0000000044d49e96>] __do_sys_bpf+0x359/0x1d90 [<00000000f601d565>] do_syscall_64+0x2d/0x40 [<0000000043d3112a>] entry_SYSCALL_64_after_hwframe+0x44/0xae BUG: memory leak unreferenced object 0xffff88810d538c80 (size 64): comm "repro", pid 2143, jiffies 4294699025 (age 8.448s) hex dump (first 32 bytes): 80 aa 19 04 00 ea ff ff 00 ab 19 04 00 ea ff ff ................ c0 ab 19 04 00 ea ff ff 80 44 28 04 00 ea ff ff .........D(..... backtrace: [<0000000077bfbfbd>] __bpf_map_area_alloc+0x31/0xc0 [<00000000587fa522>] ringbuf_map_alloc.cold.4+0x48/0x218 [<0000000044d49e96>] __do_sys_bpf+0x359/0x1d90 [<00000000f601d565>] do_syscall_64+0x2d/0x40 [<0000000043d3112a>] entry_SYSCALL_64_after_hwframe+0x44/0xae Note that both reported leaks (ffff88810d538c80 and ffff88810d538c00) correspond to pages array bpf_ringbuf is allocating and tracking properly internally. Note also that syzbot repro doesn't close FD of created BPF ringbufs, and even when ./repro itself exits with error, there are still two forked processes hanging around in my system. So clearly ringbuf maps are alive at that point. So reporting any memory leak looks weird at that point, because that memory is being used by active referenced BPF ringbuf. It's also a question why repro doesn't clean up its forks. But if I do a `pkill repro`, I do see that all the allocated memory is /properly/ cleaned up [and the] "leaks" are deallocated properly. BTW, if I add close() right after bpf() syscall in syzbot repro, I see that everything is immediately deallocated, like designed. And no memory leak is reported. So I don't think the problem is anywhere in bpf_ringbuf code, rather in the leak detection and/or repro itself. Reported-by: syzbot+5d895828587f49e7fe9b@syzkaller.appspotmail.com Signed-off-by: Rustam Kovhaev [ Daniel: also included analysis from Andrii to the commit log ] Signed-off-by: Daniel Borkmann Tested-by: syzbot+5d895828587f49e7fe9b@syzkaller.appspotmail.com Cc: Dmitry Vyukov Cc: Andrii Nakryiko Link: https://lore.kernel.org/bpf/CAEf4BzYk+dqs+jwu6VKXP-RttcTEGFe+ySTGWT9CRNkagDiJVA@mail.gmail.com Link: https://lore.kernel.org/lkml/YNTAqiE7CWJhOK2M@nuc10 Link: https://lore.kernel.org/lkml/20210615101515.GC26027@arm.com Link: https://syzkaller.appspot.com/bug?extid=5d895828587f49e7fe9b Link: https://lore.kernel.org/bpf/20210626181156.1873604-1-rkovhaev@gmail.com Signed-off-by: Sasha Levin --- kernel/bpf/ringbuf.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c index 84b3b35fc0d0..9e0c10c6892a 100644 --- a/kernel/bpf/ringbuf.c +++ b/kernel/bpf/ringbuf.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #define RINGBUF_CREATE_FLAG_MASK (BPF_F_NUMA_NODE) @@ -105,6 +106,7 @@ static struct bpf_ringbuf *bpf_ringbuf_area_alloc(size_t data_sz, int numa_node) rb = vmap(pages, nr_meta_pages + 2 * nr_data_pages, VM_ALLOC | VM_USERMAP, PAGE_KERNEL); if (rb) { + kmemleak_not_leak(pages); rb->pages = pages; rb->nr_pages = nr_pages; return rb; -- 2.30.2