Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp729038imm; Thu, 13 Sep 2018 06:56:36 -0700 (PDT) X-Google-Smtp-Source: ANB0VdY8yqpC/baYw7kcxroPVHW8bPovEn0KJ71NZ2hjudGzaSieJGKoGGxc/KcPUpS6nlhklaIH X-Received: by 2002:a63:b44c:: with SMTP id n12-v6mr7372959pgu.337.1536846996788; Thu, 13 Sep 2018 06:56:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1536846996; cv=none; d=google.com; s=arc-20160816; b=0P8jfQGJ3FF2h9HPW4pYWDBYWoMACO3ZOJbIjpD7tDANu5OcDTSIkqJp84M0AHXnUQ 17S7MQgowvmcy1iTga8ugyINFX0lcsLREivPS7b8Tabh8CHD6tlk/pbrOypnRw4jmRSV hF8fQ5i87KIgjwXUDgl8lu1yT3ZMXI3mfTGmh2lXmaxGnRt7OL/AUVTA689FJSQRvQK7 P15vugg7/UNK3So3Iy1ndZ8xdqEWhgFHjZTaO3y1/zciwWGOoOCsrqJgudS3QZgq2SaM CoINSXtW2ozasiCfEzWu2H7Z7hR009MAVdSH3EP8BEPlMchtM9ormxxUsKr78ctHHGRv 6xnA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from; bh=9a2J2aVO0bn3cC7QWq2/tuiErVXyvlVlq10lCmlHiK0=; b=rrSfamX6y8Gng0RzeTEopa8Iz0CgULnTs8+5wBGxA0MIvSVLH2ydqVONqdtHEB4oPR Hd/X1IKsbB/KH489E8VogwrpxdakFyd9y6reK79l7l9V04xclBRV7xDBXOvLdSKAmvkb bZVaiXCVY6XoZgp/P8j6bSmrmJbwv4S8A4HJuM8kTEFva1SVAByYGLpmFv+Ysy1Y3OGg pcDHvUGNRJAR36OhZDwcoSJ/Ks5un8tgYXk0iWRRcvLxqftIfq05CpuO1uxhbjHneOst H7jedKmqAhncGMsy3y0QYvjhV6uJy8Vy5/DeLblF4bNdgUzAG9VeQXtwbKQm1IkLcA2U n3OA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p2-v6si4187293pgj.391.2018.09.13.06.56.21; Thu, 13 Sep 2018 06:56:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731231AbeIMTEd (ORCPT + 99 others); Thu, 13 Sep 2018 15:04:33 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:33930 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730414AbeIMTEc (ORCPT ); Thu, 13 Sep 2018 15:04:32 -0400 Received: from localhost (ip-213-127-77-73.ip.prioritytelecom.net [213.127.77.73]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id D5442D1B; Thu, 13 Sep 2018 13:54:56 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Daniel Borkmann , John Fastabend , Song Liu , Alexei Starovoitov , Sasha Levin Subject: [PATCH 4.18 067/197] bpf, sockmap: fix leakage of smap_psock_map_entry Date: Thu, 13 Sep 2018 15:30:16 +0200 Message-Id: <20180913131844.199727283@linuxfoundation.org> X-Mailer: git-send-email 2.19.0 In-Reply-To: <20180913131841.568116777@linuxfoundation.org> References: <20180913131841.568116777@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.18-stable review patch. If anyone has any objections, please let me know. ------------------ From: Daniel Borkmann [ Upstream commit d40b0116c94bd8fc2b63aae35ce8e66bb53bba42 ] While working on sockmap I noticed that we do not always kfree the struct smap_psock_map_entry list elements which track psocks attached to maps. In the case of sock_hash_ctx_update_elem(), these map entries are allocated outside of __sock_map_ctx_update_elem() with their linkage to the socket hash table filled. In the case of sock array, the map entries are allocated inside of __sock_map_ctx_update_elem() and added with their linkage to the psock->maps. Both additions are under psock->maps_lock each. Now, we drop these elements from their psock->maps list in a few occasions: i) in sock array via smap_list_map_remove() when an entry is either deleted from the map from user space, or updated via user space or BPF program where we drop the old socket at that map slot, or the sock array is freed via sock_map_free() and drops all its elements; ii) for sock hash via smap_list_hash_remove() in exactly the same occasions as just described for sock array; iii) in the bpf_tcp_close() where we remove the elements from the list via psock_map_pop() and iterate over them dropping themselves from either sock array or sock hash; and last but not least iv) once again in smap_gc_work() which is a callback for deferring the work once the psock refcount hit zero and thus the socket is being destroyed. Problem is that the only case where we kfree() the list entry is in case iv), which at that point should have an empty list in normal cases. So in cases from i) to iii) we unlink the elements without freeing where they go out of reach from us. Hence fix is to properly kfree() them as well to stop the leakage. Given these are all handled under psock->maps_lock there is no need for deferred RCU freeing. I later also ran with kmemleak detector and it confirmed the finding as well where in the state before the fix the object goes unreferenced while after the patch no kmemleak report related to BPF showed up. [...] unreferenced object 0xffff880378eadae0 (size 64): comm "test_sockmap", pid 2225, jiffies 4294720701 (age 43.504s) hex dump (first 32 bytes): 00 01 00 00 00 00 ad de 00 02 00 00 00 00 ad de ................ 50 4d 75 5d 03 88 ff ff 00 00 00 00 00 00 00 00 PMu]............ backtrace: [<000000005225ac3c>] sock_map_ctx_update_elem.isra.21+0xd8/0x210 [<0000000045dd6d3c>] bpf_sock_map_update+0x29/0x60 [<00000000877723aa>] ___bpf_prog_run+0x1e1f/0x4960 [<000000002ef89e83>] 0xffffffffffffffff unreferenced object 0xffff880378ead240 (size 64): comm "test_sockmap", pid 2225, jiffies 4294720701 (age 43.504s) hex dump (first 32 bytes): 00 01 00 00 00 00 ad de 00 02 00 00 00 00 ad de ................ 00 44 75 5d 03 88 ff ff 00 00 00 00 00 00 00 00 .Du]............ backtrace: [<000000005225ac3c>] sock_map_ctx_update_elem.isra.21+0xd8/0x210 [<0000000030e37a3a>] sock_map_update_elem+0x125/0x240 [<000000002e5ce36e>] map_update_elem+0x4eb/0x7b0 [<00000000db453cc9>] __x64_sys_bpf+0x1f9/0x360 [<0000000000763660>] do_syscall_64+0x9a/0x300 [<00000000422a2bb2>] entry_SYSCALL_64_after_hwframe+0x44/0xa9 [<000000002ef89e83>] 0xffffffffffffffff [...] Fixes: e9db4ef6bf4c ("bpf: sockhash fix omitted bucket lock in sock_close") Fixes: 54fedb42c653 ("bpf: sockmap, fix smap_list_map_remove when psock is in many maps") Fixes: 2f857d04601a ("bpf: sockmap, remove STRPARSER map_flags and add multi-map support") Signed-off-by: Daniel Borkmann Acked-by: John Fastabend Acked-by: Song Liu Signed-off-by: Alexei Starovoitov Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/sockmap.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) --- a/kernel/bpf/sockmap.c +++ b/kernel/bpf/sockmap.c @@ -376,6 +376,7 @@ static void bpf_tcp_close(struct sock *s } raw_spin_unlock_bh(&b->lock); } + kfree(e); e = psock_map_pop(sk, psock); } rcu_read_unlock(); @@ -1685,8 +1686,10 @@ static void smap_list_map_remove(struct spin_lock_bh(&psock->maps_lock); list_for_each_entry_safe(e, tmp, &psock->maps, list) { - if (e->entry == entry) + if (e->entry == entry) { list_del(&e->list); + kfree(e); + } } spin_unlock_bh(&psock->maps_lock); } @@ -1700,8 +1703,10 @@ static void smap_list_hash_remove(struct list_for_each_entry_safe(e, tmp, &psock->maps, list) { struct htab_elem *c = rcu_dereference(e->hash_link); - if (c == hash_link) + if (c == hash_link) { list_del(&e->list); + kfree(e); + } } spin_unlock_bh(&psock->maps_lock); }