Received: by 10.223.185.111 with SMTP id b44csp903641wrg; Fri, 9 Mar 2018 16:27:42 -0800 (PST) X-Google-Smtp-Source: AG47ELsYRJ9k964j2DX0KI9tfcIeCn7emTUyAY501kE6LEKpvDDdchgEEtBwY847WGiJTUMsJ/kE X-Received: by 2002:a17:902:5489:: with SMTP id e9-v6mr332366pli.81.1520641662533; Fri, 09 Mar 2018 16:27:42 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520641662; cv=none; d=google.com; s=arc-20160816; b=KDCeR4TBMK5urTC8wYItSPOJvDPyZXYXB4QSJlcKp1XD88bvePkD4nbfw3MA1mjVJ3 d7rbGcdS/w0XCysrtsJHJ5DOgJ+WLMTlEDhhAdBXCMlLzf//NDAyPYkpoXMDsL+2JIs0 OcFw27yHpenBVV4UBA1jwkVlJMg4AyQAeja9Q1TqKshH24wh6mrN6dES3xoTJ+swE6zf u4BvQydxSAVwPfHW7f4M0O1+kWlgSXGRAdGs7FPhfawzA2xccVGew5gSiVQHnqVtv0/O 9ev6X+K5KvwdAzsh9bCMD0y5gcxIs6qRle0ONDvhu7Dz/NpbdhLNaqQUfKB9lKIqVH+I yc0A== 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=7SHuI/2JQcsTs6lTq9JFtXSPrHD3gTZ1+MQL+FW1cMc=; b=M2Cx8nzZohfC5ZBGMvBlKFV08okJ/inGPGANdGatH0cWGW49aEbTOkIrkT5LjUJnll RgDkYC6XUwJpKB0QixDSOKc2bZa4JYZKlZnPdaRNMyAmmjJhX6Y1pmQIRkkSxWoxaDbo jasi5eExtMT04M31qegHe9hd+ajBGeqpARLLL+Aa9NeXJrYB9/lU7m6HkdwQkjK8eXq5 7dmj7zQo0ye4wjB1v9MdcVJy3EdIdckS7wglVIHqAD2fSJ4oubf3ARKRbsC+PAvp9/YP E+iAUQfzlZ6mf1IRApsmYuZ/lS+aVH4msPpJRHm1/lgGdvsmHbvSe2h+vWfNcEH45oYb a3mQ== 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 18si1749585pfh.118.2018.03.09.16.27.28; Fri, 09 Mar 2018 16:27:42 -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 S934227AbeCJA0B (ORCPT + 99 others); Fri, 9 Mar 2018 19:26:01 -0500 Received: from mail.linuxfoundation.org ([140.211.169.12]:40882 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933798AbeCJAXg (ORCPT ); Fri, 9 Mar 2018 19:23:36 -0500 Received: from localhost (unknown [185.236.200.248]) by mail.linuxfoundation.org (Postfix) with ESMTPSA id 590C2DA6; Sat, 10 Mar 2018 00:23:35 +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.15 01/11] bpf: fix mlock precharge on arraymaps Date: Fri, 9 Mar 2018 16:19:15 -0800 Message-Id: <20180310001834.624988627@linuxfoundation.org> X-Mailer: git-send-email 2.16.2 In-Reply-To: <20180310001834.560857664@linuxfoundation.org> References: <20180310001834.560857664@linuxfoundation.org> User-Agent: quilt/0.65 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.15-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 | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) --- a/kernel/bpf/arraymap.c +++ b/kernel/bpf/arraymap.c @@ -52,11 +52,11 @@ static int bpf_array_alloc_percpu(struct static struct bpf_map *array_map_alloc(union bpf_attr *attr) { bool percpu = attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY; - int numa_node = bpf_map_attr_numa_node(attr); + int ret, numa_node = bpf_map_attr_numa_node(attr); 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; /* check sanity of attributes */ if (attr->max_entries == 0 || attr->key_size != 4 || @@ -101,8 +101,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, numa_node); @@ -118,20 +129,13 @@ static struct bpf_map *array_map_alloc(u array->map.max_entries = attr->max_entries; array->map.map_flags = attr->map_flags; array->map.numa_node = numa_node; + 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 || - bpf_array_alloc_percpu(array)) { + if (percpu && 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; }