From patchwork Thu Sep 27 23:26:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 975960 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=wand.net.nz Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="TZuZoKCU"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42LrZ42fW1z9s4Z for ; Fri, 28 Sep 2018 09:27:24 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728300AbeI1Fry (ORCPT ); Fri, 28 Sep 2018 01:47:54 -0400 Received: from mail-yb1-f177.google.com ([209.85.219.177]:36239 "EHLO mail-yb1-f177.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727635AbeI1Frx (ORCPT ); Fri, 28 Sep 2018 01:47:53 -0400 Received: by mail-yb1-f177.google.com with SMTP id 5-v6so1885110ybf.3 for ; Thu, 27 Sep 2018 16:27:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=H7LU0XgFhyOQYMQDmiDkHh7CHJiTZRIsq53ukEbCbIk=; b=TZuZoKCULXQ+Zcsfs2BfY2LC1mtL2cqCshAdxF2pmqVWcJPTiIa2qyjTkezdHvLZau FyMlnksqs0k43HYYMIPSu1wEO5rGv2BItwnn3FkkktZvtrrzfuP0fffD+e4iY1XVoCLv DFScooX2V8927ABNcBlrmaim2ZRjse8o4swXQ12NIZrQTYVLRqXrQ1VezemUqEupmFOC TdpLI4fU+fT2LIQi9deTUScptPfwc/q10Gn9mZHQG7Ghr0Kli/KT/6XprUPnvx10hpeG bq1/NR0A4hMaddv4LdG/GbeTz4jXkqdn+SnMXRAPlPSR3ps9ozIqzvGkVIP3JI9bJO1q HUAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=H7LU0XgFhyOQYMQDmiDkHh7CHJiTZRIsq53ukEbCbIk=; b=lEkOnNckcBlCQfC0mHTu0+ILaF2OHr1T2RV+2+4cRnDE9dREbON45oS3+tU/dNw2QK wfYDR1Gtbcxs8xhdZNHMXC3qSc2ispdBoTLTeZNBcnBPWM7nDL/3GhN0nzs7cbW3nG9J /m+UWMyFRYXhCaZXc72MewSWlocpQ2b//6xFBC+Z1aK9vwRXyjgcfDjfax4cojc+Xgrs ozdSStcfjWbfQs76/RAaVxP7v/GROqg4IrwZNBULNjdS3wtOak8PKhkyE1T6tKXul9dm biwEd46cqI1PV0UOVtaB9e+5fuOWl6KTw1jVAjr0P8NBhp8ygnxJhg8zlnGvc51DHeYl 9LLQ== X-Gm-Message-State: ABuFfohDvS7hvCFzScmIFhMFqM3Aa5qM9COY4ZXmhE2d/+YMG70tbNL3 bx4JDg5NWJANZHSQeewa2sI= X-Google-Smtp-Source: ACcGV63KbD8VQZfOQl4MOrmVSUQLFfVtEa7R+NWZYOGhJ/sWbwq+AHKHMJ8DgeXZ4wdMrfQxM4IBiQ== X-Received: by 2002:a25:7811:: with SMTP id t17-v6mr7369337ybc.436.1538090828083; Thu, 27 Sep 2018 16:27:08 -0700 (PDT) Received: from localhost.localdomain ([99.0.85.34]) by smtp.gmail.com with ESMTPSA id w6-v6sm4810717ywg.3.2018.09.27.16.27.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 27 Sep 2018 16:27:07 -0700 (PDT) From: Joe Stringer To: daniel@iogearbox.net Cc: netdev@vger.kernel.org, ast@kernel.org, john.fastabend@gmail.com, tgraf@suug.ch, kafai@fb.com, nitin.hande@gmail.com, mauricio.vasquez@polito.it Subject: [PATCHv3 bpf-next 03/12] bpf: Generalize ptr_or_null regs check Date: Thu, 27 Sep 2018 16:26:50 -0700 Message-Id: <20180927232659.14348-4-joe@wand.net.nz> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180927232659.14348-1-joe@wand.net.nz> References: <20180927232659.14348-1-joe@wand.net.nz> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org This check will be reused by an upcoming commit for conditional jump checks for sockets. Refactor it a bit to simplify the later commit. Signed-off-by: Joe Stringer Acked-by: Alexei Starovoitov --- kernel/bpf/verifier.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 87b75efc1dc1..bbb0a812ee81 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -249,6 +249,11 @@ static bool type_is_pkt_pointer(enum bpf_reg_type type) type == PTR_TO_PACKET_META; } +static bool reg_type_may_be_null(enum bpf_reg_type type) +{ + return type == PTR_TO_MAP_VALUE_OR_NULL; +} + /* string representation of 'enum bpf_reg_type' */ static const char * const reg_type_str[] = { [NOT_INIT] = "?", @@ -3600,12 +3605,10 @@ static void reg_combine_min_max(struct bpf_reg_state *true_src, } } -static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id, - bool is_null) +static void mark_ptr_or_null_reg(struct bpf_reg_state *reg, u32 id, + bool is_null) { - struct bpf_reg_state *reg = ®s[regno]; - - if (reg->type == PTR_TO_MAP_VALUE_OR_NULL && reg->id == id) { + if (reg_type_may_be_null(reg->type) && reg->id == id) { /* Old offset (both fixed and variable parts) should * have been known-zero, because we don't allow pointer * arithmetic on pointers that might be NULL. @@ -3618,11 +3621,13 @@ static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id, } if (is_null) { reg->type = SCALAR_VALUE; - } else if (reg->map_ptr->inner_map_meta) { - reg->type = CONST_PTR_TO_MAP; - reg->map_ptr = reg->map_ptr->inner_map_meta; - } else { - reg->type = PTR_TO_MAP_VALUE; + } else if (reg->type == PTR_TO_MAP_VALUE_OR_NULL) { + if (reg->map_ptr->inner_map_meta) { + reg->type = CONST_PTR_TO_MAP; + reg->map_ptr = reg->map_ptr->inner_map_meta; + } else { + reg->type = PTR_TO_MAP_VALUE; + } } /* We don't need id from this point onwards anymore, thus we * should better reset it, so that state pruning has chances @@ -3635,8 +3640,8 @@ static void mark_map_reg(struct bpf_reg_state *regs, u32 regno, u32 id, /* The logic is similar to find_good_pkt_pointers(), both could eventually * be folded together at some point. */ -static void mark_map_regs(struct bpf_verifier_state *vstate, u32 regno, - bool is_null) +static void mark_ptr_or_null_regs(struct bpf_verifier_state *vstate, u32 regno, + bool is_null) { struct bpf_func_state *state = vstate->frame[vstate->curframe]; struct bpf_reg_state *reg, *regs = state->regs; @@ -3644,14 +3649,14 @@ static void mark_map_regs(struct bpf_verifier_state *vstate, u32 regno, int i, j; for (i = 0; i < MAX_BPF_REG; i++) - mark_map_reg(regs, i, id, is_null); + mark_ptr_or_null_reg(®s[i], id, is_null); for (j = 0; j <= vstate->curframe; j++) { state = vstate->frame[j]; for_each_spilled_reg(i, state, reg) { if (!reg) continue; - mark_map_reg(&state->stack[i].spilled_ptr, 0, id, is_null); + mark_ptr_or_null_reg(reg, id, is_null); } } } @@ -3853,12 +3858,14 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env, /* detect if R == 0 where R is returned from bpf_map_lookup_elem() */ if (BPF_SRC(insn->code) == BPF_K && insn->imm == 0 && (opcode == BPF_JEQ || opcode == BPF_JNE) && - dst_reg->type == PTR_TO_MAP_VALUE_OR_NULL) { - /* Mark all identical map registers in each branch as either + reg_type_may_be_null(dst_reg->type)) { + /* Mark all identical registers in each branch as either * safe or unknown depending R == 0 or R != 0 conditional. */ - mark_map_regs(this_branch, insn->dst_reg, opcode == BPF_JNE); - mark_map_regs(other_branch, insn->dst_reg, opcode == BPF_JEQ); + mark_ptr_or_null_regs(this_branch, insn->dst_reg, + opcode == BPF_JNE); + mark_ptr_or_null_regs(other_branch, insn->dst_reg, + opcode == BPF_JEQ); } else if (!try_match_pkt_pointers(insn, dst_reg, ®s[insn->src_reg], this_branch, other_branch) && is_pointer_value(env, insn->dst_reg)) {