Received: by 10.223.185.111 with SMTP id b44csp905646wrg; Fri, 9 Mar 2018 16:30:49 -0800 (PST) X-Google-Smtp-Source: AG47ELt7RYRZON/GFwvgD6Fmdl/LaM0DI9+y9QBD5F26W/S+HZLZqEQ+hnilaS4ItNyF20aAZGD7 X-Received: by 10.98.110.71 with SMTP id j68mr323531pfc.93.1520641849799; Fri, 09 Mar 2018 16:30:49 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520641849; cv=none; d=google.com; s=arc-20160816; b=hCTPuv4YVTJW1dIfky2/gpAhDQMTg0ksla6gq+MspyBf2SnHNHEGWuyydBzwzHxbDJ g8cINI7/6JtFZQ8CWJ0U95r0eRI/p/J0DWHqw8ZIs1cot/RPUHS2HE+geCZr5OL5LySt jMAT/sdww+WDSgwwcFK7ThMD2Ax6oAUObpWpz5EgAeaph7nBI9wbIz75n0GdKSnBa5S9 MMAyLf12fjdvWQOZr6cgI5Y+jKcqoAlUuqV3ZHHsP+KeVa3cUOaWapqiJGgsRzuonRUO pBFSp+kaU90383L4/+JK77XKgwabOMsW3umjwFrFuSWaTN1yNVDcGxwJu54BD90EDcs4 5o1A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=GIjT+ylj7ARHm2XNzXmb/JPlJ+EacUnRCA+6W/IJjMc=; b=0+PtLt5Drg9q0rWZDs+R6Js9TcfbiXEv1Sb90IP4u2WGJQ7mVtJv2sa9fwFMaP4aPy LN1JqqXzOrZ0ArD1QH5e68uP80LMWjcPuD0ssm/bRhb+d65AhW5JySFbEAAPmCxwXzds aEWEdQsbCVSROQBgJN16ZdXyFjJK2cX5c22PSLBhPs1qxN0wJd7YxlxpxbMpbPvXGlIx Ewg3qfrwGR/Q0i/vyqKKJ3K8Q5d9dVBqAu2gqydR2vTqFFpAOo1WdtQ4MIiCyh35t3MY tty25an2eY9K4itTrA5iTzQvo39LzZJyRgN3abjrPVUD1JcRbwEdZhJRn6+YnhVsSjim r+xw== 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 m189si1691146pfc.410.2018.03.09.16.30.35; Fri, 09 Mar 2018 16:30:49 -0800 (PST) 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 S933887AbeCJA3V (ORCPT + 99 others); Fri, 9 Mar 2018 19:29:21 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:40306 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S934002AbeCJAXB (ORCPT ); Fri, 9 Mar 2018 19:23:01 -0500 Received: from localhost (unknown [185.236.200.248]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 5653811A2; Sat, 10 Mar 2018 00:23:00 +0000 (UTC) From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, "ast@kernel.org, daniel@iogearbox.net, stable@vger.kernel.org, Dennis Zhou" , syzbot+adb03f3f0bb57ce3acda@syzkaller.appspotmail.com, Daniel Borkmann , Alexei Starovoitov , Dennis Zhou Subject: [PATCH 4.9 60/65] bpf: fix mlock precharge on arraymaps Date: Fri, 9 Mar 2018 16:19:00 -0800 Message-Id: <20180310001830.129847750@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180310001824.927996722@linuxfoundation.org> References: <20180310001824.927996722@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 4.9-stable review patch. If anyone has any objections, please let me know. ------------------ From: Daniel Borkmann [ upstream commit 9c2d63b843a5c8a8d0559cc067b5398aa5ec3ffc ] syzkaller recently triggered OOM during percpu map allocation; while there is work in progress by Dennis Zhou to add __GFP_NORETRY semantics for percpu allocator under pressure, there seems also a missing bpf_map_precharge_memlock() check in array map allocation. Given today the actual bpf_map_charge_memlock() happens after the find_and_alloc_map() in syscall path, the bpf_map_precharge_memlock() is there to bail out early before we go and do the map setup work when we find that we hit the limits anyway. Therefore add this for array map as well. Fixes: 6c9059817432 ("bpf: pre-allocate hash map elements") Fixes: a10423b87a7e ("bpf: introduce BPF_MAP_TYPE_PERCPU_ARRAY map") Reported-by: syzbot+adb03f3f0bb57ce3acda@syzkaller.appspotmail.com Signed-off-by: Daniel Borkmann Cc: Dennis Zhou Signed-off-by: Alexei Starovoitov Signed-off-by: Daniel Borkmann Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/arraymap.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c @@ -48,8 +48,9 @@ static struct bpf_map *array_map_alloc(u bool percpu = attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY; u32 elem_size, index_mask, max_entries; bool unpriv = !capable(CAP_SYS_ADMIN); + u64 cost, array_size, mask64; struct bpf_array *array; - u64 array_size, mask64; + int ret; /* check sanity of attributes */ if (attr->max_entries == 0 || attr->key_size != 4 || @@ -92,8 +93,19 @@ static struct bpf_map *array_map_alloc(u array_size += (u64) max_entries * elem_size; /* make sure there is no u32 overflow later in round_up() */ - if (array_size >= U32_MAX - PAGE_SIZE) + cost = array_size; + if (cost >= U32_MAX - PAGE_SIZE) return ERR_PTR(-ENOMEM); + if (percpu) { + cost += (u64)attr->max_entries * elem_size * num_possible_cpus(); + if (cost >= U32_MAX - PAGE_SIZE) + return ERR_PTR(-ENOMEM); + } + cost = round_up(cost, PAGE_SIZE) >> PAGE_SHIFT; + + ret = bpf_map_precharge_memlock(cost); + if (ret < 0) + return ERR_PTR(ret); /* allocate all map elements and zero-initialize them */ array = bpf_map_area_alloc(array_size); @@ -108,20 +120,15 @@ static struct bpf_map *array_map_alloc(u array->map.value_size = attr->value_size; array->map.max_entries = attr->max_entries; array->map.map_flags = attr->map_flags; + array->map.pages = cost; array->elem_size = elem_size; - if (!percpu) - goto out; - - array_size += (u64) attr->max_entries * elem_size * num_possible_cpus(); - - if (array_size >= U32_MAX - PAGE_SIZE || - elem_size > PCPU_MIN_UNIT_SIZE || bpf_array_alloc_percpu(array)) { + if (percpu && + (elem_size > PCPU_MIN_UNIT_SIZE || + bpf_array_alloc_percpu(array))) { bpf_map_area_free(array); return ERR_PTR(-ENOMEM); } -out: - array->map.pages = round_up(array_size, PAGE_SIZE) >> PAGE_SHIFT; return &array->map; }