Received: by 2002:a05:6902:102b:0:0:0:0 with SMTP id x11csp6680ybt; Tue, 23 Jun 2020 13:49:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxnMG3aYAYYiKusijraDutL0rWqqDgIoh5QIZ18iRXtsK/87xLSfzSb7Vt7bZT7G2RphPg7 X-Received: by 2002:a17:906:1394:: with SMTP id f20mr13522066ejc.114.1592945392429; Tue, 23 Jun 2020 13:49:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592945392; cv=none; d=google.com; s=arc-20160816; b=szFQrRaNubk1yQ2tcpxb80u5R1rTgtmB6qKYAyM8BYa3jOt1E6VCGIdHJgvE3+KSNc G4REKgigwEdEcGpNeDXZdOnceDsThJjg8iM/8bXUy+n4DRDUwzvXzktGvcFuOOBEjwn+ v3EI08y3BT5LN8kJcggx8v+UWSIGuRqiftOUFPGUUaHXCk4CuBYg3nyjQrTJmdTn9HcB X3FxxxhB9lRCLVmSerLVLiruzSbAfB0bPHRTa28CGdWzQgFCewTXL1HBB5znoRZLEf9+ pzbBPU7ilvt8nKwdCihRdLpqxEzPsdQ+Dm+FB14kquZ95ukHvjLphv7VS+1VIb6AMiN0 m7Mg== 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=SmuZcZpNmKu5tNlDk7+dsUmsr76/7BIfvOwEtEpRjHc=; b=D/0naqCJXfuD73Pw16DO84Kd3TJZ5jlWc4FST2DN2b154qjYrh8QA0QvSNevUgCZ01 FFYvXgz+Lpqid3sRXVrvNQzUFgGwH3PvyXJVn8C1Y4AigVUQ+NefP2+qrIU8bWgn2j3U sCEV0fJ377gQtDNwOwW3jH+j4RV+I8pnYFFngn9Lg/+RUIgGzXCShffsKVCmozhzyQpq wqwemQUT7ziJTiFhXr3eDsrCiJbVioRlZBbcT3AonSykRidhuz3DFgKVKJw+vd0a5Hng UqgtZkNOaqkFG5eDMFDhSziTIn4Hppq6B6Iuk2mYTdcDJ+j5bKJ47h5+33x4eucCAvbs OAKw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=ISju+LuQ; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id lh24si11663244ejb.700.2020.06.23.13.49.29; Tue, 23 Jun 2020 13:49:52 -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=@kernel.org header.s=default header.b=ISju+LuQ; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392235AbgFWUsD (ORCPT + 99 others); Tue, 23 Jun 2020 16:48:03 -0400 Received: from mail.kernel.org ([198.145.29.99]:46740 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2404081AbgFWUr6 (ORCPT ); Tue, 23 Jun 2020 16:47:58 -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 C218021548; Tue, 23 Jun 2020 20:47:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1592945278; bh=xVcMwRcZOs9nllUUvgVRYPKnljVcY/QurHMY3v/zMn4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ISju+LuQa5r7Qc3R2WnCKJiwfW9kpqYlB8cK30l76AxfCld76Dsc2kdh2kjeuQ26R 2esmPL7v2OSq4y7qy7lG8QIxy8YZr8DucfoiSPmMVL0boc39X2E9eDJof80fxxmTnH 5SZgVV17EFB+vQZcZMLoDjiUvS42sD8VzQYwF0qA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Catalin Marinas , James Morse , Luis Machado , Will Deacon , Sasha Levin Subject: [PATCH 4.14 109/136] arm64: hw_breakpoint: Dont invoke overflow handler on uaccess watchpoints Date: Tue, 23 Jun 2020 21:59:25 +0200 Message-Id: <20200623195309.158032743@linuxfoundation.org> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200623195303.601828702@linuxfoundation.org> References: <20200623195303.601828702@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: Will Deacon [ Upstream commit 24ebec25fb270100e252b19c288e21bd7d8cc7f7 ] Unprivileged memory accesses generated by the so-called "translated" instructions (e.g. STTR) at EL1 can cause EL0 watchpoints to fire unexpectedly if kernel debugging is enabled. In such cases, the hw_breakpoint logic will invoke the user overflow handler which will typically raise a SIGTRAP back to the current task. This is futile when returning back to the kernel because (a) the signal won't have been delivered and (b) userspace can't handle the thing anyway. Avoid invoking the user overflow handler for watchpoints triggered by kernel uaccess routines, and instead single-step over the faulting instruction as we would if no overflow handler had been installed. (Fixes tag identifies the introduction of unprivileged memory accesses, which exposed this latent bug in the hw_breakpoint code) Cc: Catalin Marinas Cc: James Morse Fixes: 57f4959bad0a ("arm64: kernel: Add support for User Access Override") Reported-by: Luis Machado Signed-off-by: Will Deacon Signed-off-by: Sasha Levin --- arch/arm64/kernel/hw_breakpoint.c | 44 ++++++++++++++++++------------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c index 95697a9c12451..6e96cea99a4ec 100644 --- a/arch/arm64/kernel/hw_breakpoint.c +++ b/arch/arm64/kernel/hw_breakpoint.c @@ -738,6 +738,27 @@ static u64 get_distance_from_watchpoint(unsigned long addr, u64 val, return 0; } +static int watchpoint_report(struct perf_event *wp, unsigned long addr, + struct pt_regs *regs) +{ + int step = is_default_overflow_handler(wp); + struct arch_hw_breakpoint *info = counter_arch_bp(wp); + + info->trigger = addr; + + /* + * If we triggered a user watchpoint from a uaccess routine, then + * handle the stepping ourselves since userspace really can't help + * us with this. + */ + if (!user_mode(regs) && info->ctrl.privilege == AARCH64_BREAKPOINT_EL0) + step = 1; + else + perf_bp_event(wp, regs); + + return step; +} + static int watchpoint_handler(unsigned long addr, unsigned int esr, struct pt_regs *regs) { @@ -747,7 +768,6 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr, u64 val; struct perf_event *wp, **slots; struct debug_info *debug_info; - struct arch_hw_breakpoint *info; struct arch_hw_breakpoint_ctrl ctrl; slots = this_cpu_ptr(wp_on_reg); @@ -785,25 +805,13 @@ static int watchpoint_handler(unsigned long addr, unsigned int esr, if (dist != 0) continue; - info = counter_arch_bp(wp); - info->trigger = addr; - perf_bp_event(wp, regs); - - /* Do we need to handle the stepping? */ - if (is_default_overflow_handler(wp)) - step = 1; + step = watchpoint_report(wp, addr, regs); } - if (min_dist > 0 && min_dist != -1) { - /* No exact match found. */ - wp = slots[closest_match]; - info = counter_arch_bp(wp); - info->trigger = addr; - perf_bp_event(wp, regs); - /* Do we need to handle the stepping? */ - if (is_default_overflow_handler(wp)) - step = 1; - } + /* No exact match found? */ + if (min_dist > 0 && min_dist != -1) + step = watchpoint_report(slots[closest_match], addr, regs); + rcu_read_unlock(); if (!step) -- 2.25.1