From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jiong Wang Subject: [PATCH bpf-next 1/2] bpf: let verifier to calculate and record max_pkt_offset Date: Thu, 8 Nov 2018 04:08:42 -0500 Message-ID: <1541668123-9571-2-git-send-email-jiong.wang@netronome.com> References: <1541668123-9571-1-git-send-email-jiong.wang@netronome.com> Cc: netdev@vger.kernel.org, oss-drivers@netronome.com, Jiong Wang To: ast@kernel.org, daniel@iogearbox.net Return-path: Received: from mail-wr1-f68.google.com ([209.85.221.68]:37094 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726133AbeKHSnp (ORCPT ); Thu, 8 Nov 2018 13:43:45 -0500 Received: by mail-wr1-f68.google.com with SMTP id o15-v6so16726434wrv.4 for ; Thu, 08 Nov 2018 01:09:12 -0800 (PST) In-Reply-To: <1541668123-9571-1-git-send-email-jiong.wang@netronome.com> Sender: netdev-owner@vger.kernel.org List-ID: In check_packet_access, update max_pkt_offset after the offset has passed __check_packet_access. It should be safe to use u32 for max_pkt_offset as explained in code comment. Also, when there is tail call, the max_pkt_offset of the called program is unknown, so conservatively set max_pkt_offset to MAX_PACKET_OFF for such case. Reviewed-by: Jakub Kicinski Signed-off-by: Jiong Wang --- include/linux/bpf.h | 1 + kernel/bpf/verifier.c | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 33014ae..b6a296e 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -293,6 +293,7 @@ struct bpf_prog_aux { atomic_t refcnt; u32 used_map_cnt; u32 max_ctx_offset; + u32 max_pkt_offset; u32 stack_depth; u32 id; u32 func_cnt; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 98fa0be..6a248d8 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1452,6 +1452,17 @@ static int check_packet_access(struct bpf_verifier_env *env, u32 regno, int off, verbose(env, "R%d offset is outside of the packet\n", regno); return err; } + + /* __check_packet_access has made sure "off + size - 1" is within u16. + * reg->umax_value can't be bigger than MAX_PACKET_OFF which is 0xffff, + * otherwise find_good_pkt_pointers would have refused to set range info + * that __check_packet_access would have rejected this pkt access. + * Therefore, "off + reg->umax_value + size - 1" won't overflow u32. + */ + env->prog->aux->max_pkt_offset = + max_t(u32, env->prog->aux->max_pkt_offset, + off + reg->umax_value + size - 1); + return err; } @@ -6128,6 +6139,7 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) */ prog->cb_access = 1; env->prog->aux->stack_depth = MAX_BPF_STACK; + env->prog->aux->max_pkt_offset = MAX_PACKET_OFF; /* mark bpf_tail_call as different opcode to avoid * conditional branch in the interpeter for every normal -- 2.7.4