From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933954AbbIDVG2 (ORCPT ); Fri, 4 Sep 2015 17:06:28 -0400 Received: from mail-yk0-f181.google.com ([209.85.160.181]:32805 "EHLO mail-yk0-f181.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933786AbbIDVGX (ORCPT ); Fri, 4 Sep 2015 17:06:23 -0400 Date: Fri, 4 Sep 2015 14:06:19 -0700 From: Alexei Starovoitov To: Tycho Andersen Cc: Kees Cook , Alexei Starovoitov , Will Drewry , Oleg Nesterov , Andy Lutomirski , Pavel Emelyanov , "Serge E. Hallyn" , Daniel Borkmann , linux-kernel@vger.kernel.org, netdev@vger.kernel.org Subject: Re: [PATCH 6/6] ebpf: allow BPF_REG_X in src_reg conditional jumps Message-ID: <20150904210619.GF1842@Alexeis-MacBook-Pro-2.local> References: <1441382664-17437-1-git-send-email-tycho.andersen@canonical.com> <1441382664-17437-7-git-send-email-tycho.andersen@canonical.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1441382664-17437-7-git-send-email-tycho.andersen@canonical.com> User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Sep 04, 2015 at 10:04:24AM -0600, Tycho Andersen wrote: > The classic converter generates conditional jumps with: > > if (BPF_SRC(fp->code) == BPF_K && (int) fp->k < 0) { > ... > } else { > insn->dst_reg = BPF_REG_A; > insn->src_reg = BPF_REG_X; > insn->imm = fp->k; > bpf_src = BPF_SRC(fp->code); > } > > but here, we enforce that the src_reg == BPF_REG_0. We should also allow > BPF_REG_X since that's what the converter generates; this enables us to > load eBPF programs that were generated by the converter. good catch. classic->extended converter is just being untidy. It shouldn't be populating unused 'src_reg' field when BPF_SRC == BPF_K verifier is doing the right thing. It's rejecting instructions that have junk in unused fields to make sure that someday we can extend it with something useful. The fix should be something like this: diff --git a/net/core/filter.c b/net/core/filter.c index 13079f03902e..05a04ea87172 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -478,9 +478,9 @@ do_pass: bpf_src = BPF_X; } else { insn->dst_reg = BPF_REG_A; - insn->src_reg = BPF_REG_X; insn->imm = fp->k; bpf_src = BPF_SRC(fp->code); + insn->src_reg = bpf_src == BPF_X ? BPF_REG_X : 0; }