Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp4588124yba; Sun, 12 May 2019 17:07:46 -0700 (PDT) X-Google-Smtp-Source: APXvYqxuv/P9jVrbiMIfazLfSwXk4PO3/UQ5yfa8aM1SG1Gvkogr66TRanlGodMhjfK4FlpQJNZl X-Received: by 2002:aa7:81d1:: with SMTP id c17mr10111096pfn.174.1557706065992; Sun, 12 May 2019 17:07:45 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1557706065; cv=none; d=google.com; s=arc-20160816; b=tBSxxJoIUA33t0FquUh056sCq9Vp0esU/FsoAh3mmhopmhqJwd+balFfLK7zPvA4bk gkDyNlQAaXT8AyBuZtHnxXcSKmbfV5IOSE6gN2lI7u2RsUUQBXO6Yg/qthKLhqrvwlOT hZoKNDvmXmJb2gaZTBec0873nxp0FWU5rTepwaddT5M+ZAr0qdJPQ8IhKUGvh3W+HK8y o/co/rV1Y3VevFO+bsuDDmbxq2YEHHHPJzjGByYs7LnWrrBl+c7ub2WJm8405C1tR738 D6y3YcKhvmK7VZjSk0qCjc2E9Q4Oy+fTIMoq3MF3KCDOYySJaZYz2KxDOqQqYTILfV9G Pxqg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=jiIeW0+ZockKLN0QnggXMPnco/VaK0scoKYvfx0RxOU=; b=u5syn8lS7LNoPXRmwejEYOZzd3dQJR8VuTK2xaPTLfU9bjq96VIQUNWhvspSJk3YH8 q7vtWhhYEHVhzTMLZTpwEst0O4E2l/o8sSfsZHuazb5ieJ47M2C0NQvPSQ8N//J/pSNN B3UPc6y1wgkLNV3/D8qxGGUPZZESb+jBIcWhlLmFaIydFcsdMdEOErZWqi+7Ws6FehwZ uhX+pmbPfTg8pR5N0YmvfLvYiHkJlmn79uFwCE8asT5kOfjw2rwrWJ/H9IrjHa5n9xw5 4+OJJPpQ6dkxiE56k6Uz0Af3FsXLY9LqIjbaRPwk3iHKyAtvLDkotsjhsDNYeJGg6gy7 hyOQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 197si15661504pgg.33.2019.05.12.17.07.03; Sun, 12 May 2019 17:07:45 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727210AbfEMABz (ORCPT + 99 others); Sun, 12 May 2019 20:01:55 -0400 Received: from www62.your-server.de ([213.133.104.62]:35528 "EHLO www62.your-server.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727182AbfEMABz (ORCPT ); Sun, 12 May 2019 20:01:55 -0400 Received: from [78.46.172.2] (helo=sslproxy05.your-server.de) by www62.your-server.de with esmtpsa (TLSv1.2:DHE-RSA-AES256-GCM-SHA384:256) (Exim 4.89_1) (envelope-from ) id 1hPyPf-0006RU-Ki; Mon, 13 May 2019 02:01:51 +0200 Received: from [178.199.41.31] (helo=linux.home) by sslproxy05.your-server.de with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.89) (envelope-from ) id 1hPyPf-000MHZ-EX; Mon, 13 May 2019 02:01:51 +0200 Subject: Re: [PATCH bpf v1] bpf: Fix undefined behavior in narrow load handling To: Krzesimir Nowak Cc: bpf@vger.kernel.org, Alban Crequy , =?UTF-8?Q?Iago_L=c3=b3pez_Galeiras?= , Yonghong Song , Alexei Starovoitov , Martin KaFai Lau , Song Liu , netdev@vger.kernel.org, linux-kernel@vger.kernel.org References: <20190508160859.4380-1-krzesimir@kinvolk.io> <46056c60-f106-e539-b614-498cb1e9e3d0@iogearbox.net> From: Daniel Borkmann Message-ID: <8fd60de9-356a-656a-4acb-43ecab28e3da@iogearbox.net> Date: Mon, 13 May 2019 02:01:50 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 8bit X-Authenticated-Sender: daniel@iogearbox.net X-Virus-Scanned: Clear (ClamAV 0.100.3/25447/Sun May 12 09:56:54 2019) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 05/10/2019 12:16 PM, Krzesimir Nowak wrote: > On Thu, May 9, 2019 at 11:30 PM Daniel Borkmann wrote: >> On 05/08/2019 06:08 PM, Krzesimir Nowak wrote: >>> Commit 31fd85816dbe ("bpf: permits narrower load from bpf program >>> context fields") made the verifier add AND instructions to clear the >>> unwanted bits with a mask when doing a narrow load. The mask is >>> computed with >>> >>> (1 << size * 8) - 1 >>> >>> where "size" is the size of the narrow load. When doing a 4 byte load >>> of a an 8 byte field the verifier shifts the literal 1 by 32 places to >>> the left. This results in an overflow of a signed integer, which is an >>> undefined behavior. Typically the computed mask was zero, so the >>> result of the narrow load ended up being zero too. >>> >>> Cast the literal to long long to avoid overflows. Note that narrow >>> load of the 4 byte fields does not have the undefined behavior, >>> because the load size can only be either 1 or 2 bytes, so shifting 1 >>> by 8 or 16 places will not overflow it. And reading 4 bytes would not >>> be a narrow load of a 4 bytes field. >>> >>> Reviewed-by: Alban Crequy >>> Reviewed-by: Iago López Galeiras >>> Fixes: 31fd85816dbe ("bpf: permits narrower load from bpf program context fields") >>> Cc: Yonghong Song >>> Signed-off-by: Krzesimir Nowak >>> --- >>> kernel/bpf/verifier.c | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c >>> index 09d5d972c9ff..950fac024fbb 100644 >>> --- a/kernel/bpf/verifier.c >>> +++ b/kernel/bpf/verifier.c >>> @@ -7296,7 +7296,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) >>> insn->dst_reg, >>> shift); >>> insn_buf[cnt++] = BPF_ALU64_IMM(BPF_AND, insn->dst_reg, >>> - (1 << size * 8) - 1); >>> + (1ULL << size * 8) - 1); >>> } >> >> Makes sense, good catch & thanks for the fix! >> >> Could you also add a test case to test_verifier.c so we keep track of this? >> >> Thanks, >> Daniel > > Hi, > > A test for it is a bit tricky. I only found two 64bit fields that can > be loaded narrowly - `sample_period` and `addr` in `struct > bpf_perf_event_data`, so in theory I could have a test like follows: > > { > "32bit loads of a 64bit field (both least and most significant words)", > .insns = { > BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1, offsetof(struct > bpf_perf_event_data, addr)), > BPF_LDX_MEM(BPF_W, BPF_REG_4, BPF_REG_1, offsetof(struct > bpf_perf_event_data, addr) + 4), > BPF_MOV64_IMM(BPF_REG_0, 0), > BPF_EXIT_INSN(), > }, > .result = ACCEPT, > .prog_type = BPF_PROG_TYPE_PERF_EVENT, > }, > > The test like this would check that the program is not rejected, but > it wasn't an issue. The test does not check if the verifier has > transformed the narrow reads properly. Ideally the BPF program would > do something like this: > > /* let's assume that low and high variables get their values from narrow load */ > __u64 low = (__u32)perf_event->addr; > __u64 high = (__u32)(perf_event->addr >> 32); > __u64 addr = low | (high << 32); > > return addr != perf_event->addr; > > But the test_verifier.c won't be able to run this, because > BPF_PROG_TYPE_PERF_EVENT programs are not supported by the > bpf_test_run_prog function. > > Any hints how to proceed here? The test_verifier actually also runs the programs after successful verification, so above C-like snippet should be converted to BPF asm. Search for ".retval" in some of the test cases. (I've for now applied the fix itself to bpf, but still expect such test case as follow-up for same tree. Thanks!) > Cheers, > Krzesimir >