From patchwork Thu Aug 20 09:21:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 265650 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 77FBDC433E3 for ; Thu, 20 Aug 2020 10:35:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 574A9208DB for ; Thu, 20 Aug 2020 10:35:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1597919746; bh=lu8YdjRAoO37AzoS6BKU+m9uMfPbro2rrdOyBq4AXxA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:List-ID:From; b=S1OqElKvTdNWySpa7NvHYxZFDgplfQNc/H6r8Kfd7Pa4AynnIFeJ/RqLg7P5H4w6F kYfEEmpGK3oR5jZS8Ar0raOMSn3nvv8SbCQbnRHja9qkxKAUMpUrIsywGkbbwlKzvz 1YNtDH4KPCNLEZ8EqgZFNp+83ZWdiONN5sp/eaWQ= Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731237AbgHTKSr (ORCPT ); Thu, 20 Aug 2020 06:18:47 -0400 Received: from mail.kernel.org ([198.145.29.99]:41340 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731390AbgHTKSl (ORCPT ); Thu, 20 Aug 2020 06:18:41 -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 A909D2078D; Thu, 20 Aug 2020 10:18:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1597918719; bh=lu8YdjRAoO37AzoS6BKU+m9uMfPbro2rrdOyBq4AXxA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YKB1T7KXJPRMEOXM7N7bALIpxx7l/OVs4K0gg0GHLG5HoDKTjg7WimbMhYIWS5t8H H/rQPPyryB5ADhVxx26gOUZ2PzskZbbPKYChrmn0jK753W6sjsSuCZyArtDbGVfxrJ i04I4pnqBf+iHDnp0esKtuZQKha0jr9lJoGcUu5I= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Luis Machado , Will Deacon , Russell King , Sasha Levin Subject: [PATCH 4.4 012/149] ARM: 8986/1: hw_breakpoint: Dont invoke overflow handler on uaccess watchpoints Date: Thu, 20 Aug 2020 11:21:29 +0200 Message-Id: <20200820092126.284846663@linuxfoundation.org> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200820092125.688850368@linuxfoundation.org> References: <20200820092125.688850368@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Will Deacon [ Upstream commit eec13b42d41b0f3339dcf0c4da43734427c68620 ] Unprivileged memory accesses generated by the so-called "translated" instructions (e.g. LDRT) in kernel mode can cause user watchpoints to fire unexpectedly. 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. Cc: Fixes: f81ef4a920c8 ("ARM: 6356/1: hw-breakpoint: add ARM backend for the hw-breakpoint framework") Reported-by: Luis Machado Tested-by: Luis Machado Signed-off-by: Will Deacon Signed-off-by: Russell King Signed-off-by: Sasha Levin --- arch/arm/kernel/hw_breakpoint.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index abcbea1ae30ba..78c6be1b27145 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -688,6 +688,12 @@ static void disable_single_step(struct perf_event *bp) arch_install_hw_breakpoint(bp); } +static int watchpoint_fault_on_uaccess(struct pt_regs *regs, + struct arch_hw_breakpoint *info) +{ + return !user_mode(regs) && info->ctrl.privilege == ARM_BREAKPOINT_USER; +} + static void watchpoint_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { @@ -747,16 +753,27 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr, } pr_debug("watchpoint fired: address = 0x%x\n", info->trigger); + + /* + * 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 (watchpoint_fault_on_uaccess(regs, info)) + goto step; + perf_bp_event(wp, regs); /* - * If no overflow handler is present, insert a temporary - * mismatch breakpoint so we can single-step over the - * watchpoint trigger. + * Defer stepping to the overflow handler if one is installed. + * Otherwise, insert a temporary mismatch breakpoint so that + * we can single-step over the watchpoint trigger. */ - if (!wp->overflow_handler) - enable_single_step(wp, instruction_pointer(regs)); + if (wp->overflow_handler) + goto unlock; +step: + enable_single_step(wp, instruction_pointer(regs)); unlock: rcu_read_unlock(); }