Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp3287728ybb; Tue, 31 Mar 2020 02:09:08 -0700 (PDT) X-Google-Smtp-Source: ADFU+vvk3D9QHGibKsfGeO/Sb/EG4wd0BAPtgohLHC5+KY2sSCIIN3I2fHCxSjngdDt/kddEXNV5 X-Received: by 2002:a9d:b8f:: with SMTP id 15mr12108576oth.256.1585645748793; Tue, 31 Mar 2020 02:09:08 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1585645748; cv=none; d=google.com; s=arc-20160816; b=kVjEzj/Eu8PmV5LJl7YWRoxqtXiQp154akQa3qc0TF3cp+KNDq8Ghm4QR2czI5N5Oz en5pEVwzCK4cTGkV/ib9nI8EzbOdoCLKJtHXoQ+8KI/LNwuN7rwjwFYiznwlNX+PeHPG S5/mc9RRGwFTj1d+uhQDGeNlUgyXdDWCIt3LepK4eYK/EqjVFPDdjt/jqYQNZ36QMza+ QW77HTKBVEeoMrP50UkudAXtXfcXW+BwAQNJiJf23pmQlez31ly9VFrMok7A/dSH7fjC Lh7uWEbXobHi+gY5Z4D1MPuZOJJyQP8p7LOVG9XWqKic66yE5keWA/aGiJdr/TQfkdkW thqw== 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:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=P1GehgF4dMztA2DV7QkgC2gNxn1YWaai5umtPKX15PE=; b=KpFH8tQLwV4Z67DmENk1jhklfkttZ5z36rNM5OMM1obFL6PbtjkVQ2/6CZbzJTdK66 V55Bebb9uMW9cg2c7+hK8iCl6abbo4hXl9KFc1XagpBSk6naAePlaMT0E5Qyt6VS2PoB BCVVgqSzAfyc9q7RVt7Lxc2CbUC8Rzzlg2ys8jZ9xRdw8+Y3ODoLlckYrqY+qjA9U+7/ s43lwthrbNl8ABEKxUxFp5KCG2wGsDGTCr00nw9SjhDXxWTdAtxTIrl3ezm0XS+9PGd6 iTngSn1uQsicNmsaoQBbcDMRq2beDGZrsD0Z9JkQJRahRZ8uC++hwo0pZJvi4B9wh1w9 qkNw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=PsYS3PkF; 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 h1si7172298otr.127.2020.03.31.02.08.55; Tue, 31 Mar 2020 02:09:08 -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; dkim=pass header.i=@kernel.org header.s=default header.b=PsYS3PkF; 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 S1731368AbgCaJIi (ORCPT + 99 others); Tue, 31 Mar 2020 05:08:38 -0400 Received: from mail.kernel.org ([198.145.29.99]:51120 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730570AbgCaJIf (ORCPT ); Tue, 31 Mar 2020 05:08:35 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id B726F2072E; Tue, 31 Mar 2020 09:08:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1585645714; bh=Tj/iq0FRyUK/KJfzZTg+0+d4QNo001tjbb7+70vHkUY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PsYS3PkFWv94gHxV+WZM2er/Dau1subeq7z3JvE54vSQ5ync4DsDzbaFmZygTMCDm XGf//FPjQB77Ku4ImrMEcIW3x1OPxdHNrJQJ3DwNPITtNHExT8Cx/CCDnnPfKS7eS6 /PhB2xmcUMLfOLFpx38or0Zkrzc17WgvWzQOoLzc= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Xi Wang , Luke Nelson , Daniel Borkmann Subject: [PATCH 5.5 140/170] bpf, x32: Fix bug with JMP32 JSET BPF_X checking upper bits Date: Tue, 31 Mar 2020 10:59:14 +0200 Message-Id: <20200331085438.307159701@linuxfoundation.org> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200331085423.990189598@linuxfoundation.org> References: <20200331085423.990189598@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Luke Nelson commit 80f1f85036355e5581ec0b99913410345ad3491b upstream. The current x32 BPF JIT is incorrect for JMP32 JSET BPF_X when the upper 32 bits of operand registers are non-zero in certain situations. The problem is in the following code: case BPF_JMP | BPF_JSET | BPF_X: case BPF_JMP32 | BPF_JSET | BPF_X: ... /* and dreg_lo,sreg_lo */ EMIT2(0x23, add_2reg(0xC0, sreg_lo, dreg_lo)); /* and dreg_hi,sreg_hi */ EMIT2(0x23, add_2reg(0xC0, sreg_hi, dreg_hi)); /* or dreg_lo,dreg_hi */ EMIT2(0x09, add_2reg(0xC0, dreg_lo, dreg_hi)); This code checks the upper bits of the operand registers regardless if the BPF instruction is BPF_JMP32 or BPF_JMP64. Registers dreg_hi and dreg_lo are not loaded from the stack for BPF_JMP32, however, they can still be polluted with values from previous instructions. The following BPF program demonstrates the bug. The jset64 instruction loads the temporary registers and performs the jump, since ((u64)r7 & (u64)r8) is non-zero. The jset32 should _not_ be taken, as the lower 32 bits are all zero, however, the current JIT will take the branch due the pollution of temporary registers from the earlier jset64. mov64 r0, 0 ld64 r7, 0x8000000000000000 ld64 r8, 0x8000000000000000 jset64 r7, r8, 1 exit jset32 r7, r8, 1 mov64 r0, 2 exit The expected return value of this program is 2; under the buggy x32 JIT it returns 0. The fix is to skip using the upper 32 bits for jset32 and compare the upper 32 bits for jset64 only. All tests in test_bpf.ko and selftests/bpf/test_verifier continue to pass with this change. We found this bug using our automated verification tool, Serval. Fixes: 69f827eb6e14 ("x32: bpf: implement jitting of JMP32") Co-developed-by: Xi Wang Signed-off-by: Xi Wang Signed-off-by: Luke Nelson Signed-off-by: Daniel Borkmann Link: https://lore.kernel.org/bpf/20200305234416.31597-1-luke.r.nels@gmail.com Signed-off-by: Greg Kroah-Hartman --- arch/x86/net/bpf_jit_comp32.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) --- a/arch/x86/net/bpf_jit_comp32.c +++ b/arch/x86/net/bpf_jit_comp32.c @@ -2039,10 +2039,12 @@ static int do_jit(struct bpf_prog *bpf_p } /* and dreg_lo,sreg_lo */ EMIT2(0x23, add_2reg(0xC0, sreg_lo, dreg_lo)); - /* and dreg_hi,sreg_hi */ - EMIT2(0x23, add_2reg(0xC0, sreg_hi, dreg_hi)); - /* or dreg_lo,dreg_hi */ - EMIT2(0x09, add_2reg(0xC0, dreg_lo, dreg_hi)); + if (is_jmp64) { + /* and dreg_hi,sreg_hi */ + EMIT2(0x23, add_2reg(0xC0, sreg_hi, dreg_hi)); + /* or dreg_lo,dreg_hi */ + EMIT2(0x09, add_2reg(0xC0, dreg_lo, dreg_hi)); + } goto emit_cond_jmp; } case BPF_JMP | BPF_JSET | BPF_K: