From patchwork Fri Sep 21 17:10:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joe Stringer X-Patchwork-Id: 973328 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="uCyHbMgB"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42H0VS4XW2z9sB5 for ; Sat, 22 Sep 2018 03:10:56 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2390868AbeIUXAn (ORCPT ); Fri, 21 Sep 2018 19:00:43 -0400 Received: from mail-yw1-f53.google.com ([209.85.161.53]:38336 "EHLO mail-yw1-f53.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2390788AbeIUXAm (ORCPT ); Fri, 21 Sep 2018 19:00:42 -0400 Received: by mail-yw1-f53.google.com with SMTP id n21-v6so5461797ywh.5 for ; Fri, 21 Sep 2018 10:10:54 -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=KuQO3YlC5yz5UMhcC8meR7eSVgxdhS2LWqtRrEWTTOA=; b=uCyHbMgBLb+BQQp4E4zipYdXgtm7fer6nPt6T+NSCrld7C9pbHUvtAiqtYMfCn3RoV vGQgiOkHNxjNMaq83g5uAQCr1IgKYn0/0T1PB7v9WGUJRTzpZeSas3xI7faTxqTVcHJw FXM8y7I4wK/xv1JeRu6tPd5qr8eS6KzSLPZ8tpjcLMyh0CmJzZpMo6lMeMkvY2ZvAefa Kh2evO5l+lGDfSHud+j2tepaah3sXCLaBKiiRjZiUo7N8yUhOrpSKXiGl+JYKtrQ5Wnc fqlgt9oTNVIBI1Wd2bIG675UXdMuTTaxS5lgLRQzJ3zOPllqrYa9DccxuMgC1uRFizVc N8iw== 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=KuQO3YlC5yz5UMhcC8meR7eSVgxdhS2LWqtRrEWTTOA=; b=h52DOK+ofru1lCIscrQm31WC/itvVsFND8Cn7O2xnfjXgpHZ+gJmyjWk4fqOJNtJk8 /qQp6JDAKcAu0jH36OflX/irB5n1yYWMZUfl/SkQuLc6/mrrTP2IGs8QXpMxpaMCov0u kO3u9NsDZc0vTcYha5KIaDPxF1qg7EGIDa3esfZIYuDnZDkYu/U4LhJYECzAjU3yMR/6 HAfHv3xTvIPndZbhtwCjIZRgAM5tN9d2rgdyRZA03Iymur/aksy9SiMHpMbxOERJ+Fgg 6ce1NqNXvEWhgtdU4VOP3TBGZtXOHSVL8x99NPlPiX6jfdpVKeC/0i4ucs/EKAAJlDWN ZMeg== X-Gm-Message-State: APzg51AseUQbypj1MYwDeN42qy+em0oWIsc7b9ZwDjNGYiRpwlH1t6oF cQxsg4AkLgZB0FflVPVldO0= X-Google-Smtp-Source: ANB0VdaC9KKX8GPvsag/0ryYCkT6E2Euk5XuLWtuYAx97b3TCfVnF71ebgCRgWMThfyqkporbqZQIQ== X-Received: by 2002:a0d:e8d5:: with SMTP id r204-v6mr4969265ywe.90.1537549853735; Fri, 21 Sep 2018 10:10:53 -0700 (PDT) Received: from localhost.localdomain ([99.0.85.34]) by smtp.gmail.com with ESMTPSA id h10-v6sm9930972ywa.35.2018.09.21.10.10.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 21 Sep 2018 10:10:53 -0700 (PDT) From: Joe Stringer To: ast@kernel.org Cc: netdev@vger.kernel.org, daniel@iogearbox.net, john.fastabend@gmail.com, tgraf@suug.ch, kafai@fb.com, nitin.hande@gmail.com, mauricio.vasquez@polito.it Subject: [PATCHv2 bpf-next 03/11] bpf: Generalize ptr_or_null regs check Date: Fri, 21 Sep 2018 10:10:35 -0700 Message-Id: <20180921171043.20823-4-joe@wand.net.nz> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180921171043.20823-1-joe@wand.net.nz> References: <20180921171043.20823-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 a889398ba43d..7dccb18ede03 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] = "?", @@ -3598,12 +3603,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. @@ -3616,11 +3619,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 @@ -3633,8 +3638,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; @@ -3642,14 +3647,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); } } } @@ -3851,12 +3856,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)) {