Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp4576858pxv; Tue, 6 Jul 2021 04:28:43 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzQ1sRDc/i9ZZbUKpQCjQdtLBYnB+hFM8rVH6Zzp0e5JZdufIa9Gk3Vb//3KqEICRJzd/I/ X-Received: by 2002:a92:6412:: with SMTP id y18mr15045327ilb.158.1625570923706; Tue, 06 Jul 2021 04:28:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625570923; cv=none; d=google.com; s=arc-20160816; b=xIlYJ1t00kXE/ahU4cn3q+HcZ6aVDh/06rn0vkxUn5kpb2XwILqVYeyvYi13Z9N7OU VuffKLLdp36oAZ1W5Bx7RGFmKKmzdong7Oj+BNMrvEh4hfJ48nCwoJ96cpPAT9vuNRqN aJ1UV0LTuYARUY3Vylmror9i3w+3DanzAoyAsJV5BsnKH/WVeB68J40nzkm5uWoJTFQm cxPga/339NdwLVnjRpJHAuzYVg8vA5yB98g6e4Uoc5r2nKRwuPw9x1zuXQOfEaeExRkV Ts0sx+gWWDerLc7dVdaZaNAsSfKnSCd6XMj607O0mOJLbvQyXPYN5ZurVyxbFhTTD/5E d6Ow== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=wzqbM7jf3ju3R5RPPWlc0TMnBITv6iusvf0vhUVYxL8=; b=vU6WYlh0FnCiGlRfDCgKOozZkEYu999SX1bs81vXUloyK6Q4g3aTHeEXHsiBO6o+vI NZKTSLYrE0GxXLSOwKQUJYOVn8i39//DuzeYqkh3x4GoHumrS9ZpihaklWbJ2CTHyuMf FVR0t6IRVPPXlybfD8FB3ZnnIngGxDjhrepd9eu4JmVJPnsl0bgLrAVCIc3tej2ca1s0 WbIC4pO77YWRE/7Tqmcl1ZHuxCw/vD4xC4GmTyQFS9QCMRyQC62+AfvrtQGcPT3o0SfX dstxFsGjMgYf40hT3t5UZQTLTv1KH2Owr02uOfkPE18LxqQSOFZuyxfqKgqDWKtt6Gu1 FupA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="I/SBOK4r"; 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=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id r16si18457648ilt.87.2021.07.06.04.28.31; Tue, 06 Jul 2021 04:28:43 -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=@kernel.org header.s=k20201202 header.b="I/SBOK4r"; 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=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235315AbhGFL3y (ORCPT + 99 others); Tue, 6 Jul 2021 07:29:54 -0400 Received: from mail.kernel.org ([198.145.29.99]:56654 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234156AbhGFLXv (ORCPT ); Tue, 6 Jul 2021 07:23:51 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id CA19D61CF6; Tue, 6 Jul 2021 11:18:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1625570294; bh=0XRFg5hIq6dpQhf6aGNiDBR8wtXCngnhyGCW3ADbjSA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I/SBOK4r4sJj2SL73IkYkBCghYPt7Moun1BR21+2T6lUageP0eWks4rxqS2zXgP1K Bf8RASvsKmvBPnSFqh9qTx5sXxMmaDQDFQEezpmf+ZLiRfDqqxkChFxve2dgEQmnrn HJW1HhA5VwoMzDN5cfMjLGFv3dqUvzn9p1WYNQk9xFU52DMElB2jQbiY92OFh33Msb ar7PylZGsP+HXxaX+32/JxWk+0rPLQLjfvXiiWj9/7ADu22x5l+GjTmZC2BRzDl3/m u0T3wrJ6tia+t5FJYBEobfiZeRnqh+yEnI+6LJQemAZS9XRKwof81zKHm3j9BOaC7s NNks1vEFIkDnw== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Rustam Kovhaev , syzbot+5d895828587f49e7fe9b@syzkaller.appspotmail.com, Daniel Borkmann , Dmitry Vyukov , Andrii Nakryiko , Sasha Levin , netdev@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH AUTOSEL 5.13 183/189] bpf: Fix false positive kmemleak report in bpf_ringbuf_area_alloc() Date: Tue, 6 Jul 2021 07:14:03 -0400 Message-Id: <20210706111409.2058071-183-sashal@kernel.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210706111409.2058071-1-sashal@kernel.org> References: <20210706111409.2058071-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore 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