Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp657018pxv; Thu, 15 Jul 2021 12:39:41 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyhqFk6KywA/cX5dDecthLGzd2xEsHAWcB5LURv9pCv9N0PU2Wm0CGzU7BXwiwONy4JqXpw X-Received: by 2002:a17:906:1997:: with SMTP id g23mr7167741ejd.304.1626377980757; Thu, 15 Jul 2021 12:39:40 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626377980; cv=none; d=google.com; s=arc-20160816; b=g6790CM9FosJCLZkBegXC+yIvee1pwgm3p/HOpsD/RFVlyT5PBe4E/VeHEXEBsuZon nqaA6r+PBZQSAASfywgAlh/X1SK7cCtRNC2htZZfHtEYdV8z58BIVHYqOju9wEbfH9X7 2uRBTwH71TUDFaxQ4Ze01qLNZZB+dT7fQxylfA94nyZSBA99sOsJPbeJGJsPLz8vKW+l bkYDchXk4tEqhW/4FZ2mNQMDwKOZJGQu1kfbYyDxHbbeLIcMYofbkhGAUdI+F5Kzn3jn UIsfwjG4c4x4XJLNZ7ri7dSlXa2jlIldEskKRZ45tBBhkgXlEUt7Oif3Yn1ohNwum8v+ Jqvg== 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=BMaE8fPsvQcRBGDRPDukWVibOlu2tF5zS9emADr+nxJgYS/cTchEoUSb5jiK1VN5Y3 HUKdE0SqWTC+ITESJhfBIhDQaQp7Q2gCWbdycICqN5giJnyew13zcnlslY3mTJ9qg4FW khPxjYe9AghqoY6h2G7Z2b+481x7PP5G92vPm2hIQDr9Goc0kNsFbRerE23C0a65f54q V5cBpxQsgdzANrTpp61DRl31PcMqGLd9ieoaNKLnO6bt1L5+K66DrnOTVR2qDdQKNv2r aXy3yOF8fCmk38NtEggpya8qYjXbbU+Pv+HJ+LBQY1cw9jlK/Ni7Jw3BoMw6EHI/sZ+A o7HQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=ifBV18tI; 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 r24si8448407edp.42.2021.07.15.12.39.17; Thu, 15 Jul 2021 12:39:40 -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=ifBV18tI; 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 S244049AbhGOTiv (ORCPT + 99 others); Thu, 15 Jul 2021 15:38:51 -0400 Received: from mail.kernel.org ([198.145.29.99]:52808 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244247AbhGOTOh (ORCPT ); Thu, 15 Jul 2021 15:14:37 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id CF6CD613D0; Thu, 15 Jul 2021 19:09:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626376199; bh=0XRFg5hIq6dpQhf6aGNiDBR8wtXCngnhyGCW3ADbjSA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ifBV18tIkUd7a9U/7Dy5QSO7pfJA/xeX9ua9sH+xPnsTXaU5GtAf9fSVsdC6azO3m Jja4HOzLt8I/1xhcBqi8RsugeLpsJwYokCQxgb0T19AmYfXPkR8hX3opTdKh+WYcSp Me04TPAinI7ir484h5tmrk2KF1Z/J4yk9+zKjxko= 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.13 170/266] bpf: Fix false positive kmemleak report in bpf_ringbuf_area_alloc() Date: Thu, 15 Jul 2021 20:38:45 +0200 Message-Id: <20210715182642.329830306@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210715182613.933608881@linuxfoundation.org> References: <20210715182613.933608881@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