Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp550918pxv; Thu, 1 Jul 2021 04:19:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwbvI5Y4OqJB/7iNUdZYlLePToyoel0KwD8XIvCef1QIBZCxMH8nELpfnap8zs3QliNiZ4M X-Received: by 2002:a05:6402:350e:: with SMTP id b14mr52782678edd.286.1625138342283; Thu, 01 Jul 2021 04:19:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625138342; cv=none; d=google.com; s=arc-20160816; b=gBA70VIJtlyT5yN+gNqnHqMSjojHCRp1sU5XtOLvuF/MVpxqzsJRfwLMRS0h489job 5N62W0rw8j3Rqy2QEiTV3jFSoafYJeu2QKtfXSABjcBc1NF6CEb83EQXHQrGo7ZC3Fz1 DcaSEBJ/QMokuKAG/R40/q4L8AzZ4dpaFWJ2wDchCRXOR6T7KPAgQkTIWP7M3sOsgpKm 1fI7etyIO+UkVWpux7MzLrefFJdprV/Yrg0P/Fyyel0ETpaK5PDyf7pARo5uKJ0kfjlS /O6rWQMYOmAp2AzoWa3mHdvt3As2ypKAbKynDiSSjoqwSo/1hxo7z9Ugw6x8tUpe4rlu mcEA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:date:cc:to:subject:from:message-id; bh=SEQrocHCSOqXltW6Nzs15gEEHE4fUO+ujLHBIavzq98=; b=zJV4nPGKmtq9cNTUHtdle5TFVK+4EXqKFwvDvZfUKZV3BfKW+qjfF0zlDmfGL1sdvR 8vT5uFiqzKg7ei/os9owNjSaUMEE2JEVCGaDlYpvMmFAeV3S63I918dKEONS28UJ/3iP WNLHYye+507TnmQjyW8auLbCwnW+H9EdFWLO+5cwm8mw3/x6xJDVINKL7xMu5040GcOH rd83NGuSti/EC4J+FiGFEjozWylBS/L5OWb0ZcDBxbx8b5XuirUQQYPjnOTpMCEalkI4 iEngv0/+5FOSCuDJD75RgpZAGXM42nR3k2HUYKyKx6BQi0sL95DUZ82yRefp0tspSDro o5Wg== ARC-Authentication-Results: i=1; mx.google.com; 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 n2si30692786ejl.693.2021.07.01.04.18.38; Thu, 01 Jul 2021 04:19:02 -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; 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 S236119AbhGALTn (ORCPT + 99 others); Thu, 1 Jul 2021 07:19:43 -0400 Received: from pegase1.c-s.fr ([93.17.236.30]:52718 "EHLO pegase1.c-s.fr" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236040AbhGALTm (ORCPT ); Thu, 1 Jul 2021 07:19:42 -0400 Received: from localhost (mailhub3.si.c-s.fr [192.168.12.233]) by localhost (Postfix) with ESMTP id 4GFwfG1JNGzBDd1; Thu, 1 Jul 2021 13:17:10 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase1.c-s.fr ([192.168.12.234]) by localhost (pegase1.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 9iG8UJUbAIoV; Thu, 1 Jul 2021 13:17:10 +0200 (CEST) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase1.c-s.fr (Postfix) with ESMTP id 4GFwfG0R6KzBDb6; Thu, 1 Jul 2021 13:17:10 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id D7A078B8F9; Thu, 1 Jul 2021 13:17:09 +0200 (CEST) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id rl1aU70ZKTna; Thu, 1 Jul 2021 13:17:09 +0200 (CEST) Received: from po9473vm.idsi0.si.c-s.fr (unknown [192.168.4.90]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 1B9F18B903; Thu, 1 Jul 2021 13:17:09 +0200 (CEST) Received: by po9473vm.idsi0.si.c-s.fr (Postfix, from userid 0) id BFD336627F; Thu, 1 Jul 2021 11:17:08 +0000 (UTC) Message-Id: <024bb05105050f704743a0083fe3548702be5706.1625138205.git.christophe.leroy@csgroup.eu> From: Christophe Leroy Subject: [PATCH] powerpc/mm: Fix lockup on kernel exec fault To: Benjamin Herrenschmidt , Paul Mackerras , Michael Ellerman , npiggin@gmail.com Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Date: Thu, 1 Jul 2021 11:17:08 +0000 (UTC) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The powerpc kernel is not prepared to handle exec faults from kernel. Especially, the function is_exec_fault() will return 'false' when an exec fault is taken by kernel, because the check is based on reading current->thread.regs->trap which contains the trap from user. For instance, when provoking a LKDTM EXEC_USERSPACE test, current->thread.regs->trap is set to SYSCALL trap (0xc00), and the fault taken by the kernel is not seen as an exec fault by set_access_flags_filter(). Commit d7df2443cd5f ("powerpc/mm: Fix spurrious segfaults on radix with autonuma") made it clear and handled it properly. But later on commit d3ca587404b3 ("powerpc/mm: Fix reporting of kernel execute faults") removed that handling, introducing test based on error_code. And here is the problem, because on the 603 all upper bits of SRR1 get cleared when the TLB instruction miss handler bails out to ISI. Until commit cbd7e6ca0210 ("powerpc/fault: Avoid heavy search_exception_tables() verification"), an exec fault from kernel at a userspace address was indirectly caught by the lack of entry for that address in the exception tables. But after that commit the kernel mainly rely on KUAP or on core mm handling to catch wrong user accesses. Here the access is not wrong, so mm handles it. It is a minor fault because PAGE_EXEC is not set, set_access_flags_filter() should set PAGE_EXEC and voila. But as is_exec_fault() returns false as explained in the begining, set_access_flags_filter() bails out without setting PAGE_EXEC flag, which leads to a forever minor exec fault. As the kernel is not prepared to handle such exec faults, the thing to do is to fire in bad_kernel_fault() for any exec fault taken by the kernel, as it was prior to commit d3ca587404b3. Fixes: d3ca587404b3 ("powerpc/mm: Fix reporting of kernel execute faults") Cc: stable@vger.kernel.org Signed-off-by: Christophe Leroy --- arch/powerpc/mm/fault.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index 34f641d4a2fe..a8d0ce85d39a 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -199,9 +199,7 @@ static bool bad_kernel_fault(struct pt_regs *regs, unsigned long error_code, { int is_exec = TRAP(regs) == INTERRUPT_INST_STORAGE; - /* NX faults set DSISR_PROTFAULT on the 8xx, DSISR_NOEXEC_OR_G on others */ - if (is_exec && (error_code & (DSISR_NOEXEC_OR_G | DSISR_KEYFAULT | - DSISR_PROTFAULT))) { + if (is_exec) { pr_crit_ratelimited("kernel tried to execute %s page (%lx) - exploit attempt? (uid: %d)\n", address >= TASK_SIZE ? "exec-protected" : "user", address, -- 2.25.0