Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp22170pxb; Mon, 13 Sep 2021 11:53:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzLuVMjPtUT0RKwWm1x2G51/m8tx5uf+REgPaN0OWpltrs3ZpliAzU0MIzYfpk75vJpUcaH X-Received: by 2002:a05:6e02:1a8c:: with SMTP id k12mr2657254ilv.312.1631559203220; Mon, 13 Sep 2021 11:53:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1631559203; cv=none; d=google.com; s=arc-20160816; b=ue7ikhS1SMv+2wEJiG2myu9yGhWvLxiM2c5HPrI/HsEM88sKVtWUeK30e7Of53am4P gC6mASxRswMAYFMSLx45Ij/PdDxX/xT6k5M8vhUNAmuxS34SVX6OgF4oS4QnfLhzkkqC ER0AMxnaa8I5a5ag9Ow+Z3+fVhwhNnIip1yZ+tH0h7xz4m8TmgPQ2agIyN1bisYwbYyk 55FgZAojkgSI+KLnmra4CUDHc69hNAXMe4PyXlNnq+cFgGrClgi0HJr5NHJkI5sdpF04 nLot3HNAwTkY79rLcW4oTYnyuQ3ppvVhq6Wkjb9MlqkvNlJMvh9+N0BMXp7tGxH+fDna 8Adg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=l7WG1ITExwW6QoVvs0DFCw1eEsLE5eFK/XuhL5UOiso=; b=yuCgXDsPsrMT1zEKOeu8WzPzXRtLFqK0C7oncxDWRlKZrUlahQGGYRPFbrPPrsOw/L cenyvzQitYhhT2B50wlk9Dy/qAWbyluguYOw/qr9F7wKENh+AtccoJafI8GNlELBpM3k B3lZD64aVPGgZfnJdmoWTFVHFFrYYJNX89YScjknR6f+eVrkil2CRnOWYU4fIHbQm/VV s4G6OQ9hodgofQV/Ht9Y6+cpLFPWDXaWul2T3yaklEQmWpRFFfaU4EJzueNeu7+94j1H Of5tYy+f+iZ1lyu8j0fhcfU4zzqAkj2InpkTY67wlZXUB+dmq2XmWw1hfbgzo43OxmgT pqZw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Ob8QAFYj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id a4si8083853ilt.54.2021.09.13.11.53.09; Mon, 13 Sep 2021 11:53:23 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=Ob8QAFYj; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241751AbhIMNZb (ORCPT + 99 others); Mon, 13 Sep 2021 09:25:31 -0400 Received: from mail.kernel.org ([198.145.29.99]:37988 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240610AbhIMNXH (ORCPT ); Mon, 13 Sep 2021 09:23:07 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id 837FE61214; Mon, 13 Sep 2021 13:21:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1631539278; bh=OH2yDzer+lljY8y7adYIAqHbNINB8ZEIvHhYPqgZF0Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ob8QAFYj5HUzHoPkzlbLe52KFWTwcyLb+NqeA/3kLBFxFAnPqT485qvWlRd6lsd6e b38/k7qjCyCSKht0+Gj/Dy8d90NztfKUgb877TjhUdi0sVxEEVEtXZDCZ83AThj4Ti j8Dl6HXu5SiFlJ/LxyCG8722UkhyZzl703wcsQ3E= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Dan Carpenter , Andrey Ignatov , Alexei Starovoitov , Sasha Levin Subject: [PATCH 5.4 109/144] bpf: Fix possible out of bound write in narrow load handling Date: Mon, 13 Sep 2021 15:14:50 +0200 Message-Id: <20210913131051.587991689@linuxfoundation.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210913131047.974309396@linuxfoundation.org> References: <20210913131047.974309396@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Andrey Ignatov [ Upstream commit d7af7e497f0308bc97809cc48b58e8e0f13887e1 ] Fix a verifier bug found by smatch static checker in [0]. This problem has never been seen in prod to my best knowledge. Fixing it still seems to be a good idea since it's hard to say for sure whether it's possible or not to have a scenario where a combination of convert_ctx_access() and a narrow load would lead to an out of bound write. When narrow load is handled, one or two new instructions are added to insn_buf array, but before it was only checked that cnt >= ARRAY_SIZE(insn_buf) And it's safe to add a new instruction to insn_buf[cnt++] only once. The second try will lead to out of bound write. And this is what can happen if `shift` is set. Fix it by making sure that if the BPF_RSH instruction has to be added in addition to BPF_AND then there is enough space for two more instructions in insn_buf. The full report [0] is below: kernel/bpf/verifier.c:12304 convert_ctx_accesses() warn: offset 'cnt' incremented past end of array kernel/bpf/verifier.c:12311 convert_ctx_accesses() warn: offset 'cnt' incremented past end of array kernel/bpf/verifier.c 12282 12283 insn->off = off & ~(size_default - 1); 12284 insn->code = BPF_LDX | BPF_MEM | size_code; 12285 } 12286 12287 target_size = 0; 12288 cnt = convert_ctx_access(type, insn, insn_buf, env->prog, 12289 &target_size); 12290 if (cnt == 0 || cnt >= ARRAY_SIZE(insn_buf) || ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Bounds check. 12291 (ctx_field_size && !target_size)) { 12292 verbose(env, "bpf verifier is misconfigured\n"); 12293 return -EINVAL; 12294 } 12295 12296 if (is_narrower_load && size < target_size) { 12297 u8 shift = bpf_ctx_narrow_access_offset( 12298 off, size, size_default) * 8; 12299 if (ctx_field_size <= 4) { 12300 if (shift) 12301 insn_buf[cnt++] = BPF_ALU32_IMM(BPF_RSH, ^^^^^ increment beyond end of array 12302 insn->dst_reg, 12303 shift); --> 12304 insn_buf[cnt++] = BPF_ALU32_IMM(BPF_AND, insn->dst_reg, ^^^^^ out of bounds write 12305 (1 << size * 8) - 1); 12306 } else { 12307 if (shift) 12308 insn_buf[cnt++] = BPF_ALU64_IMM(BPF_RSH, 12309 insn->dst_reg, 12310 shift); 12311 insn_buf[cnt++] = BPF_ALU64_IMM(BPF_AND, insn->dst_reg, ^^^^^^^^^^^^^^^ Same. 12312 (1ULL << size * 8) - 1); 12313 } 12314 } 12315 12316 new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt); 12317 if (!new_prog) 12318 return -ENOMEM; 12319 12320 delta += cnt - 1; 12321 12322 /* keep walking new program and skip insns we just inserted */ 12323 env->prog = new_prog; 12324 insn = new_prog->insnsi + i + delta; 12325 } 12326 12327 return 0; 12328 } [0] https://lore.kernel.org/bpf/20210817050843.GA21456@kili/ v1->v2: - clarify that problem was only seen by static checker but not in prod; Fixes: 46f53a65d2de ("bpf: Allow narrow loads with offset > 0") Reported-by: Dan Carpenter Signed-off-by: Andrey Ignatov Signed-off-by: Alexei Starovoitov Link: https://lore.kernel.org/bpf/20210820163935.1902398-1-rdna@fb.com Signed-off-by: Sasha Levin --- kernel/bpf/verifier.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 80b219d27e37..c5ecb6147ea2 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -8957,6 +8957,10 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) if (is_narrower_load && size < target_size) { u8 shift = bpf_ctx_narrow_access_offset( off, size, size_default) * 8; + if (shift && cnt + 1 >= ARRAY_SIZE(insn_buf)) { + verbose(env, "bpf verifier narrow ctx load misconfigured\n"); + return -EINVAL; + } if (ctx_field_size <= 4) { if (shift) insn_buf[cnt++] = BPF_ALU32_IMM(BPF_RSH, -- 2.30.2