From patchwork Tue Oct 2 20:35: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: 978016 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="gmi2kJ9e"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 42PrWt1XHbz9s3C for ; Wed, 3 Oct 2018 06:35:54 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727535AbeJCDVB (ORCPT ); Tue, 2 Oct 2018 23:21:01 -0400 Received: from mail-yw1-f46.google.com ([209.85.161.46]:33640 "EHLO mail-yw1-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727450AbeJCDVA (ORCPT ); Tue, 2 Oct 2018 23:21:00 -0400 Received: by mail-yw1-f46.google.com with SMTP id m127-v6so1365341ywb.0 for ; Tue, 02 Oct 2018 13:35:51 -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=2CaCxhHhSU0AQM6muwbPmv+JSMMh1nUqaej76GmZOwA=; b=gmi2kJ9eN50rk0Z+7WmTlWNO7gRtLHoKiEZgwYNrklvCvZhjuHCDat2NVanhg9q+iN pYQB1jnA/7xHD6Bq+bviy5JXah4kAyfuU153kj2VUkF1fNmG7937yumF2D4+HrnchZR/ BeJfMRLGVcHQRGpdjyijgmBsWd4cmHtVxEZJC9zDbIGwwpc/FRcEyo5yGhkI7Bm7TBij yf43SgutAn4vt8BS9dK0k6ZLgkwFx9wSQWi7VjAjy/VmfjP0NG8jdFTg7YBwaM40N0b4 3dZf/af7OVF2nNN5bh/a/wXg9hr2LbgFm0siNJa38Lwobhh+n36bofMH1c2lQGa2z8KO NUNw== 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=2CaCxhHhSU0AQM6muwbPmv+JSMMh1nUqaej76GmZOwA=; b=sVD4poQKGTidpAFteODHi5Sqa+ha8SLkv0wWsiwQIjDtgFxkyZGku7OxTfOo5bSNmT w8C0ytklnr4hus/C5G+f4z/GrHHmKEqB7wXIbYqY4CjFFwmdzNIucTh4Z/v9769Kv07m usvw1X13hNO0BhOyMbO8oRXh5pfqWiFLUeHXrkUkmQ7pTx1sfhJHy3otLiXJZOG6jvKg ino6qsxt9ZLt6YisrutU7MExOY0LbPPSBOqcX0BZUsI2mJ5z2BSMK6LV/bZECwTx7tCz vjuEaQVEHFf4sfDsZBzm9daA8LgBEz8SDxEYYC01ytwUEjIPtF5bXu2ECTgEnS0QYYvj 8daw== X-Gm-Message-State: ABuFfohwBd5yJZOsMEPFh5Tzu445fu8ActlW75ixeN23jyx1ikOaJXaa hOkUeUl2nczHPrjBDBL6GAo= X-Google-Smtp-Source: ACcGV62mb24EIz9XPX+uxyuq633coBgSTX3kKmcjIFHqfmPQ24hIZ5MjXNfGYLNsA/N5ZMM560iPbg== X-Received: by 2002:a81:a382:: with SMTP id a124-v6mr9165829ywh.72.1538512550767; Tue, 02 Oct 2018 13:35:50 -0700 (PDT) Received: from localhost.localdomain ([99.0.85.34]) by smtp.gmail.com with ESMTPSA id o131-v6sm4555361ywb.107.2018.10.02.13.35.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Oct 2018 13:35: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: [PATCHv4 bpf-next 04/13] bpf: Generalize ptr_or_null regs check Date: Tue, 2 Oct 2018 13:35:32 -0700 Message-Id: <20181002203541.26599-5-joe@wand.net.nz> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181002203541.26599-1-joe@wand.net.nz> References: <20181002203541.26599-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 8b4e70eeced2..98b218bd46e8 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] = "?", @@ -3599,12 +3604,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. @@ -3617,11 +3620,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 @@ -3634,8 +3639,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; @@ -3643,14 +3648,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]; bpf_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); } } } @@ -3852,12 +3857,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)) {