Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp897898yba; Thu, 18 Apr 2019 11:25:02 -0700 (PDT) X-Google-Smtp-Source: APXvYqxyzulSZcdktNb/gbjfW/isxXKaP48Qej/JNWwcc/Wx7L6raDCnc+mQAlLjKKGz5zE+/Ydy X-Received: by 2002:a17:902:29c9:: with SMTP id h67mr1242664plb.114.1555611902284; Thu, 18 Apr 2019 11:25:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555611902; cv=none; d=google.com; s=arc-20160816; b=nSM1dQZj2RVH2z6S6xcpbzqXZ6TTNADSgemJNt40kR1/tKcTTpZd74juCMpd3mqf10 hu0xu2jFG3KOum3Vg2MEarCW9OBQWCXrmUq2dax+jWCPKx1dBsbrixGWMjpyoJW8Zg7d wr+mo4O7fg6qfNLqLm2284wbSLI+AFLxzpQVDW5AgTwYNVqX3GKjyfrAre22znmvbbmt mvnASvSrD9CQvpnIHinFRbklsRvGA3FmuvI2H4+MH/HhbqFBEGbFW1HKiRzJaNam6AMY +MZlXAdpR/4dYuvXgDRKMzUaiAV2ud7k6gGyPOWXGOdFRsEKZWIX7A+PBmYitN2h27pZ 0NxQ== 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:dkim-signature; bh=Ku3xeNnRGP4y3Tf8S5wfWQrKGwxzawmBgzwXSnO/Q0E=; b=c4L2as1q/kFRWXai1fhCg8xNEjgRweBfTSy3JxoVnh3zApHiQNAyohbk1tHyPYBuim LHZsoBwtbtz1vvr2wqSMlxUXYgEjhBFb4EwpSIUmPrG0QC6rPOksU4SyEDdaEwQi7neh EXRHJpugci6998XzC79KFHhypBWFDSYHvsdZ5ZMysfGwq8HGiB1U0FwhSWRVhKOujBet OIgwocAAXB4Nu1qvmce65w1uv1X+1BGEYwVAYCMkAfMGHVmhKNy9DCqsCaepfOZlDAVO Rxl1TurdLYPO9BZMbzmzE84WoC9eyM0K1h6e2uCK0VH6EtgkhxQ/bTMAgXWxu2DUGB+s nBZw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=PdFmLa7z; 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 i9si2972284pfr.111.2019.04.18.11.24.47; Thu, 18 Apr 2019 11:25:02 -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; dkim=pass header.i=@kernel.org header.s=default header.b=PdFmLa7z; 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 S2391504AbfDRSGg (ORCPT + 99 others); Thu, 18 Apr 2019 14:06:36 -0400 Received: from mail.kernel.org ([198.145.29.99]:36422 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2391118AbfDRSGd (ORCPT ); Thu, 18 Apr 2019 14:06:33 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id C712B218A1; Thu, 18 Apr 2019 18:06:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1555610792; bh=FkcgN0sC8JjFHDxYbEilXDzWfhUtVmz57J6VhZtk63s=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PdFmLa7zliFL8Pv1UishobdncBzQZ9d59yrNsW97B2o0rRPlNCSn9iq5rKY51P+On 23Har0QGXCdC28jDaCOTBrA7xACWd8lfWhbZboD/2sZP/zelttJclIvTMKQ6Inztsj OTPUhMki8IDVGUdWxe7mK3ZS8hp/AmMR39J0wtiM= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Daniel Borkmann , Martin KaFai Lau , Alexei Starovoitov , Vallish Vaidyeshwara , Balbir Singh Subject: [PATCH 4.14 86/92] bpf: fix inner map masking to prevent oob under speculation Date: Thu, 18 Apr 2019 19:57:44 +0200 Message-Id: <20190418160438.021404394@linuxfoundation.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190418160430.325165109@linuxfoundation.org> References: <20190418160430.325165109@linuxfoundation.org> User-Agent: quilt/0.66 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 From: Daniel Borkmann commit 9d5564ddcf2a0f5ba3fa1c3a1f8a1b59ad309553 upstream. During review I noticed that inner meta map setup for map in map is buggy in that it does not propagate all needed data from the reference map which the verifier is later accessing. In particular one such case is index masking to prevent out of bounds access under speculative execution due to missing the map's unpriv_array/index_mask field propagation. Fix this such that the verifier is generating the correct code for inlined lookups in case of unpriviledged use. Before patch (test_verifier's 'map in map access' dump): # bpftool prog dump xla id 3 0: (62) *(u32 *)(r10 -4) = 0 1: (bf) r2 = r10 2: (07) r2 += -4 3: (18) r1 = map[id:4] 5: (07) r1 += 272 | 6: (61) r0 = *(u32 *)(r2 +0) | 7: (35) if r0 >= 0x1 goto pc+6 | Inlined map in map lookup 8: (54) (u32) r0 &= (u32) 0 | with index masking for 9: (67) r0 <<= 3 | map->unpriv_array. 10: (0f) r0 += r1 | 11: (79) r0 = *(u64 *)(r0 +0) | 12: (15) if r0 == 0x0 goto pc+1 | 13: (05) goto pc+1 | 14: (b7) r0 = 0 | 15: (15) if r0 == 0x0 goto pc+11 16: (62) *(u32 *)(r10 -4) = 0 17: (bf) r2 = r10 18: (07) r2 += -4 19: (bf) r1 = r0 20: (07) r1 += 272 | 21: (61) r0 = *(u32 *)(r2 +0) | Index masking missing (!) 22: (35) if r0 >= 0x1 goto pc+3 | for inner map despite 23: (67) r0 <<= 3 | map->unpriv_array set. 24: (0f) r0 += r1 | 25: (05) goto pc+1 | 26: (b7) r0 = 0 | 27: (b7) r0 = 0 28: (95) exit After patch: # bpftool prog dump xla id 1 0: (62) *(u32 *)(r10 -4) = 0 1: (bf) r2 = r10 2: (07) r2 += -4 3: (18) r1 = map[id:2] 5: (07) r1 += 272 | 6: (61) r0 = *(u32 *)(r2 +0) | 7: (35) if r0 >= 0x1 goto pc+6 | Same inlined map in map lookup 8: (54) (u32) r0 &= (u32) 0 | with index masking due to 9: (67) r0 <<= 3 | map->unpriv_array. 10: (0f) r0 += r1 | 11: (79) r0 = *(u64 *)(r0 +0) | 12: (15) if r0 == 0x0 goto pc+1 | 13: (05) goto pc+1 | 14: (b7) r0 = 0 | 15: (15) if r0 == 0x0 goto pc+12 16: (62) *(u32 *)(r10 -4) = 0 17: (bf) r2 = r10 18: (07) r2 += -4 19: (bf) r1 = r0 20: (07) r1 += 272 | 21: (61) r0 = *(u32 *)(r2 +0) | 22: (35) if r0 >= 0x1 goto pc+4 | Now fixed inlined inner map 23: (54) (u32) r0 &= (u32) 0 | lookup with proper index masking 24: (67) r0 <<= 3 | for map->unpriv_array. 25: (0f) r0 += r1 | 26: (05) goto pc+1 | 27: (b7) r0 = 0 | 28: (b7) r0 = 0 29: (95) exit Fixes: b2157399cc98 ("bpf: prevent out-of-bounds speculation") Signed-off-by: Daniel Borkmann Acked-by: Martin KaFai Lau Signed-off-by: Alexei Starovoitov Signed-off-by: Vallish Vaidyeshwara Signed-off-by: Balbir Singh Signed-off-by: Greg Kroah-Hartman --- kernel/bpf/map_in_map.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) --- a/kernel/bpf/map_in_map.c +++ b/kernel/bpf/map_in_map.c @@ -12,6 +12,7 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd) { struct bpf_map *inner_map, *inner_map_meta; + u32 inner_map_meta_size; struct fd f; f = fdget(inner_map_ufd); @@ -34,7 +35,12 @@ struct bpf_map *bpf_map_meta_alloc(int i return ERR_PTR(-EINVAL); } - inner_map_meta = kzalloc(sizeof(*inner_map_meta), GFP_USER); + inner_map_meta_size = sizeof(*inner_map_meta); + /* In some cases verifier needs to access beyond just base map. */ + if (inner_map->ops == &array_map_ops) + inner_map_meta_size = sizeof(struct bpf_array); + + inner_map_meta = kzalloc(inner_map_meta_size, GFP_USER); if (!inner_map_meta) { fdput(f); return ERR_PTR(-ENOMEM); @@ -44,9 +50,16 @@ struct bpf_map *bpf_map_meta_alloc(int i inner_map_meta->key_size = inner_map->key_size; inner_map_meta->value_size = inner_map->value_size; inner_map_meta->map_flags = inner_map->map_flags; - inner_map_meta->ops = inner_map->ops; inner_map_meta->max_entries = inner_map->max_entries; + /* Misc members not needed in bpf_map_meta_equal() check. */ + inner_map_meta->ops = inner_map->ops; + if (inner_map->ops == &array_map_ops) { + inner_map_meta->unpriv_array = inner_map->unpriv_array; + container_of(inner_map_meta, struct bpf_array, map)->index_mask = + container_of(inner_map, struct bpf_array, map)->index_mask; + } + fdput(f); return inner_map_meta; }