From patchwork Wed May 9 21:07:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 911196 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="kHMPZi5q"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 40h88Z1J2Hz9s1w for ; Thu, 10 May 2018 07:08:14 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965711AbeEIVIL (ORCPT ); Wed, 9 May 2018 17:08:11 -0400 Received: from mail-ot0-f193.google.com ([74.125.82.193]:39102 "EHLO mail-ot0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S965554AbeEIVH0 (ORCPT ); Wed, 9 May 2018 17:07:26 -0400 Received: by mail-ot0-f193.google.com with SMTP id l12-v6so41799414oth.6 for ; Wed, 09 May 2018 14:07:26 -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=R02ae/uMpEi9jLT5ct7Uz+8cGVSVfjUNoxbuLTEPQc4=; b=kHMPZi5q5WzjNxXIB2Az9P7fxwXDxLYCs6d1G37oqDtYPX7NoNqQKbe/qjU0hAxv8c VnMDpd1q1JboDEQLhYJeu8+gAAx10fzqhXeEEAUpBRilk/wKeK9lLNLsjjXvJCfOP4Gf nGMvVhI17xq9/CtQ4SZ4JHp0yXlFCkt84XbboSTuSdTL6edYI/5zuH19MajsK1SsLiAR b+dU8sg+g7IuUltI+gYEwJww+m2MDHjNqdGaVO4b2pwrTVPcnezrXLufaE8fBFClcrnJ 7hHfVdF/LL3OEeViV9X6ZJvrM6HvutzYPekw7oOkW7Sbbbzr2CF3EWlbHib5PSMwPg/D d+KQ== 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=R02ae/uMpEi9jLT5ct7Uz+8cGVSVfjUNoxbuLTEPQc4=; b=U0HQY/aZC+gO4xv7OrxOmXmSY1APFNLJBaHfNXGAMFIsIJ+K7hOxALR25gkBmua0MO xoMEgjQDmQdrxMVxGUgHvUUGrNGeHxUOBkgY5K68MvYt7Pvq4hXBaH0lvQRK3U3iqLbg xdvTm4YNbOvNirorzleK11FOyFRSi2StSSoBgqNXS0NGAnA+KlRvRxxjWTMVmgac/Was 5oUnPGEk1DK1cyGRRl11o6Njb5JRUYDSh5DUPHjbjeFJZ7ztAKsYiCr4oFajdTmdqSTT PeXnNMg7paMkN8ymI4JzGx4bjmXAvWdw2Xzhc64IddcYwUtRJ81RKXiKZMOsbNQs5H62 HKpg== X-Gm-Message-State: ALQs6tALCHIfsQQu76CBzbWc5YIilKaoi1bYEHcWqhKQFcbsvDbXBBmk UtkB02IKnHM8van8UuCgFDA= X-Google-Smtp-Source: AB8JxZq2Cyry/bYhbSkalHZi7HJUybV8gk12IXjv3MXvSPrDmoka0luxPmh348x/X+cTMUlPh816CA== X-Received: by 2002:a9d:5719:: with SMTP id p25-v6mr35974022oth.282.1525900045892; Wed, 09 May 2018 14:07:25 -0700 (PDT) Received: from allosaurus.lan ([99.0.85.34]) by smtp.gmail.com with ESMTPSA id h125-v6sm13612921oic.54.2018.05.09.14.07.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 09 May 2018 14:07:25 -0700 (PDT) From: Joe Stringer To: daniel@iogearbox.net Cc: netdev@vger.kernel.org, ast@kernel.org, john.fastabend@gmail.com, kafai@fb.com Subject: [RFC bpf-next 03/11] bpf: Generalize ptr_or_null regs check Date: Wed, 9 May 2018 14:07:01 -0700 Message-Id: <20180509210709.7201-4-joe@wand.net.nz> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180509210709.7201-1-joe@wand.net.nz> References: <20180509210709.7201-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 --- 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 a32b560072d7..1b31b805dea4 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -227,6 +227,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] = "?", @@ -3531,12 +3536,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. @@ -3549,11 +3552,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 @@ -3566,8 +3571,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; @@ -3575,14 +3580,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); } } } @@ -3784,12 +3789,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)) {