Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753983AbdGUOaZ (ORCPT ); Fri, 21 Jul 2017 10:30:25 -0400 Received: from www62.your-server.de ([213.133.104.62]:44832 "EHLO www62.your-server.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753828AbdGUOaX (ORCPT ); Fri, 21 Jul 2017 10:30:23 -0400 Message-ID: <59720FF9.10901@iogearbox.net> Date: Fri, 21 Jul 2017 16:30:17 +0200 From: Daniel Borkmann User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.7.0 MIME-Version: 1.0 To: Edward Cree , davem@davemloft.net, Alexei Starovoitov , Alexei Starovoitov CC: netdev@vger.kernel.org, linux-kernel@vger.kernel.org, iovisor-dev , josef@toxicpanda.com Subject: Re: [PATCH net 2/2] bpf/verifier: fix min/max handling in BPF_SUB References: <2ebcb201-2f18-7276-f4f9-f2bbaffae179@solarflare.com> In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-Authenticated-Sender: daniel@iogearbox.net Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2192 Lines: 57 On 07/21/2017 03:37 PM, Edward Cree wrote: > We have to subtract the src max from the dst min, and vice-versa, since > (e.g.) the smallest result comes from the largest subtrahend. > > Fixes: 484611357c19 ("bpf: allow access into map value arrays") > Signed-off-by: Edward Cree LGTM, thanks for the fix! Acked-by: Daniel Borkmann > --- > kernel/bpf/verifier.c | 21 +++++++++++++++------ > 1 file changed, 15 insertions(+), 6 deletions(-) > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index af9e84a..664d939 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -1865,10 +1865,12 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, > * do our normal operations to the register, we need to set the values > * to the min/max since they are undefined. > */ > - if (min_val == BPF_REGISTER_MIN_RANGE) > - dst_reg->min_value = BPF_REGISTER_MIN_RANGE; > - if (max_val == BPF_REGISTER_MAX_RANGE) > - dst_reg->max_value = BPF_REGISTER_MAX_RANGE; > + if (opcode != BPF_SUB) { > + if (min_val == BPF_REGISTER_MIN_RANGE) > + dst_reg->min_value = BPF_REGISTER_MIN_RANGE; > + if (max_val == BPF_REGISTER_MAX_RANGE) > + dst_reg->max_value = BPF_REGISTER_MAX_RANGE; > + } > > switch (opcode) { > case BPF_ADD: > @@ -1879,10 +1881,17 @@ static void adjust_reg_min_max_vals(struct bpf_verifier_env *env, > dst_reg->min_align = min(src_align, dst_align); > break; > case BPF_SUB: > + /* If one of our values was at the end of our ranges, then the > + * _opposite_ value in the dst_reg goes to the end of our range. > + */ > + if (min_val == BPF_REGISTER_MIN_RANGE) > + dst_reg->max_value = BPF_REGISTER_MAX_RANGE; > + if (max_val == BPF_REGISTER_MAX_RANGE) > + dst_reg->min_value = BPF_REGISTER_MIN_RANGE; > if (dst_reg->min_value != BPF_REGISTER_MIN_RANGE) > - dst_reg->min_value -= min_val; > + dst_reg->min_value -= max_val; > if (dst_reg->max_value != BPF_REGISTER_MAX_RANGE) > - dst_reg->max_value -= max_val; > + dst_reg->max_value -= min_val; > dst_reg->min_align = min(src_align, dst_align); > break; > case BPF_MUL: >