From patchwork Wed Sep 12 00:36:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 968777 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="uu7pooN+"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 4292sf5YyJz9s3Z for ; Wed, 12 Sep 2018 10:36:54 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727781AbeILFil (ORCPT ); Wed, 12 Sep 2018 01:38:41 -0400 Received: from mail-oi0-f66.google.com ([209.85.218.66]:44903 "EHLO mail-oi0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726454AbeILFil (ORCPT ); Wed, 12 Sep 2018 01:38:41 -0400 Received: by mail-oi0-f66.google.com with SMTP id l82-v6so276925oih.11 for ; Tue, 11 Sep 2018 17:36:52 -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=Padk7PI82psOLsHLntziCkGZF6LtdUGN1Y1IPF4OpSg=; b=uu7pooN+hIdtshDAChtYkdnpPAe9bKGjkklSInNyjOx+H10OPg3TQvI+Maa6mcPMsx sy4rx4Bi/lrzFXz7nZUoaYMIp+S2gbBe0peEfvoK1QrbjPmZoUnRczJNkNIJauM6aovJ UX5y8YRDx+oVgQ7NAFt5TpDwIuk/aP1x9Po8/3gS0/gpU8E1cH9L8nRj69MowI7HE5rG qm7borm4ESYdJ+A+8CGST4lU9oWzjnaMWWqkzQZzomCU15PqVQtYFc/HjsqK/7SBZxDp 1z6qQFhc/TvAI220d6fPFE/5HKxwp2F5TnppOvwxe8G+0Pbl7QpohJfec8c3TJgdCtdx SIUQ== 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=Padk7PI82psOLsHLntziCkGZF6LtdUGN1Y1IPF4OpSg=; b=MNJe/pOhuLt3fY8ji/7dXwG9HoSblbcSs5qAuepOYmrytMGzbca3II2zhWUG5v8R9A 1BHU1dAMktpzdJOUMhB+gKYB1tQ1dX5i06TjR5rbnk8LMobfMyxOWPh30XVPW0CE4fvf nytFexdlnZIW5/7/d+qVoy3pPG6peM8ztD5geSZx460APgBI+uzfaHtedBub0b8zI6qo pYNOOeaaBP2FQ3p1PhHwBcZ0RJSIJs3fnOOFrz6pW4VYpb9fbsuRKnl1STPQm6n+Mhjm fz6r2YpzFpBmJHBUBl3hzAXm573qfgYOeb2bPRJ0UzStKVHWIgzResU6iqxvoXo906RW RDcA== X-Gm-Message-State: APzg51B2mPVV/xk0Wetl5kRbnyK55lYvqEgX/UahjNdqmt+TQ4klNoSM UrkIm2p0iJaPtIlbUoIZ6iWrlPj2 X-Google-Smtp-Source: ANB0VdbTcjgN6xeIAFvi1on+wkK4t+mW+cpS7HaEz/9epQRTU/ATvzAyFByN5rgT7TKTOL8TQepCkA== X-Received: by 2002:aca:31c6:: with SMTP id x189-v6mr7039813oix.213.1536712611469; Tue, 11 Sep 2018 17:36:51 -0700 (PDT) Received: from allosaurus.lan ([99.0.85.34]) by smtp.gmail.com with ESMTPSA id s145-v6sm39598850oih.16.2018.09.11.17.36.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 11 Sep 2018 17:36:50 -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: [PATCH bpf-next 03/11] bpf: Generalize ptr_or_null regs check Date: Tue, 11 Sep 2018 17:36:32 -0700 Message-Id: <20180912003640.28316-4-joe@wand.net.nz> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180912003640.28316-1-joe@wand.net.nz> References: <20180912003640.28316-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 61b60e141b6a..f2357c8c90de 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] = "?", @@ -3567,12 +3572,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. @@ -3585,11 +3588,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 @@ -3602,8 +3607,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; @@ -3611,14 +3616,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); } } } @@ -3820,12 +3825,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)) {