From patchwork Mon Jan 6 17:09:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 13927706 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C5BC3E77198 for ; Mon, 6 Jan 2025 17:13:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:Cc :To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=D8gYm1UR71yrMoa/cg1QHqKtmih1oRuAa8wG7eT7BN8=; b=X+FLeGHnEz9CpR d2ql0N4EWHYfzx9MNc4oeLB5WmrcD8tGWjlDDTVms58ut1I1So+kh1wT+i5Jj5hpZCR0jYj+jJZkn sRIZF5O8dVyD+YSH9OFwx4A6OjhbKhlSatUw020lUL3W0K+l3GwSXe9bT2lpRgvjrgxpdw7frxiul rCkNfd67zSTlC2F2FJFwDDFlP14Ul1GmBjGn+/hpJYt2RQld+uS5guKlUixbDlZP/kna3BuaEmSF8 oSs8RqeMMEx2d/zGoqWFm2x/VVHqhBQ5sQfaYbPypNcY6RTRZOA+dlXLXtgXYGNObTxPonCKJLa3C GSVBDY7EATA08arKPZTw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tUqf1-000000024xv-10vx; Mon, 06 Jan 2025 17:13:03 +0000 Received: from mail-pl1-x636.google.com ([2607:f8b0:4864:20::636]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tUqbU-000000024XN-1bpK for linux-riscv@lists.infradead.org; Mon, 06 Jan 2025 17:09:25 +0000 Received: by mail-pl1-x636.google.com with SMTP id d9443c01a7336-2164b662090so185368255ad.1 for ; Mon, 06 Jan 2025 09:09:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1736183364; x=1736788164; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=rbce092ZLczhOhH4XTVRQYxBwIS56/FODTEPeJDdcKI=; b=Vj55M9qVaLKcKuib7Xn2Kymqp8rO32tC/wcctWcm2aiPv08KaCjRjoh0oxWa+2pXu1 wbG0h28c1mWBr0Z+GulxQZI8X0gZU5O7K2zGlDluSzTIIOs7sXIbW4MNNbqFh+uQXHhv YX3TuDW8S17KjcssG0Ch5PwWgcU8cOtb3AaVeFvml33wyf6jiR8X1Inu8nB8rJWqmLPu +ahRiwfiM/fVCToKdXHbyQ7V4PQOtOwH4zsdQ1wwJ6sSMrkEB8Ze4PHxuYmoAGYYTo+H TipzgScOU//eqHXLFZpQ7M8QnCKCEPuAy9lqvJwWIIdkrBkok3TexVhntSVSiRcc3Ja5 yuhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1736183364; x=1736788164; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=rbce092ZLczhOhH4XTVRQYxBwIS56/FODTEPeJDdcKI=; b=GZvTdeLzmPJjJ7css+rYeyCFcTGhxop8l4qsyOJD9usopnCwvWJq10D0RrLpBP7Ix/ 54k/i1BcG0qI12CVrIrVgg0cxNRhjLAAt0pr0C76ZNPgIKBNgpfFFVK5VFzUpRY2+vle EiVIXh0a8JnfVxU7preIwTiuGH8xnms8gHYONXIImGOtmEi7zbzzPmVM5r91iPhHGPNH PSMg8Ml4vzL/xOzqWQoRvct/tvSKMNaw/q9KUfkIwa3EGEIDnkF8xVRQDqt80lGm2oec okyDJ7MozUfVLjxUD/9yu8RLs2UZ1yb6U5DgUTt0SZbboDjcIXedSKusUOVLnuaFC0ve GoIg== X-Forwarded-Encrypted: i=1; AJvYcCXYfcsmCbqEVPk7EFEVyfE32zCSkeoT0DrlbQJRVvU9TX180EQVQ4UlB9imZXEE/jFp0v4cGdoPiqUR6g==@lists.infradead.org X-Gm-Message-State: AOJu0Yziw9nxo7UXfRTnlmgL/83jCLB3Dr9Hy9+G5NmT/3+/M3NvwBS2 Xfm2ZU4wYXzQWRv3PaaIvV1GXBjiFA1GbpOBHBfTAqA6PpdG3yPHNLpNCOEuGao= X-Gm-Gg: ASbGncskQUan7matvyZOX3SNi7XKrb6/feFqfVWoRFChslyBeDQEJR8IQHsr6Fn2BAq Z+ErantwXClKq9n9+Bkf72WhwgLDm1OCmp2gwBPLk9XQTwHwe2lWyPXcV5vhJznIhD2OCz4zPMD odjM2FkFXmLw5cVgqtwVHNM8GjUYVBgEpS+l3JppLpuwjJgNAYWdmL7Q0GsVVKIneYUzBejJh0V kUEY/6loNSMz/Yf71Vixzb5MYpfscDSEPoyaGse/b7UJnXrIubgP91HWw== X-Google-Smtp-Source: AGHT+IHUY4CZVBm/XKZtAhXutDUGhNJ1CtZDaw4qM0q1zL+zzKqxOLozbGljgiIr1MNwrItiL0PUzQ== X-Received: by 2002:a05:6a21:6f87:b0:1e0:c432:32fe with SMTP id adf61e73a8af0-1e5e04a444fmr86089298637.26.1736183363740; Mon, 06 Jan 2025 09:09:23 -0800 (PST) Received: from carbon-x1.. ([2a01:e0a:e17:9700:16d2:7456:6634:9626]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-72aad8163fdsm31602646b3a.6.2025.01.06.09.09.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Jan 2025 09:09:23 -0800 (PST) From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Paul Walmsley , Palmer Dabbelt , linux-riscv@lists.infradead.org (open list:RISC-V ARCHITECTURE), linux-kernel@vger.kernel.org (open list) Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , Samuel Holland , Alexandre Ghiti Subject: [PATCH v2] riscv: misaligned: disable pagefault before accessing user memory Date: Mon, 6 Jan 2025 18:09:08 +0100 Message-ID: <20250106170911.1403467-1-cleger@rivosinc.com> X-Mailer: git-send-email 2.47.1 MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250106_090924_690434_34A16481 X-CRM114-Status: GOOD ( 15.18 ) X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-riscv" Errors-To: linux-riscv-bounces+linux-riscv=archiver.kernel.org@lists.infradead.org Calling copy_{from/to}_user() in interrupt context might actually sleep and display a BUG message: [ 10.377019] BUG: sleeping function called from invalid context at include/linux/uaccess.h:162 [ 10.379868] in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 88, name: ssh-keygen [ 10.380009] preempt_count: 0, expected: 0 [ 10.380324] CPU: 0 UID: 0 PID: 88 Comm: ssh-keygen Not tainted 6.13.0-rc5-00013-g3435cd5f1331-dirty #19 [ 10.380639] Hardware name: riscv-virtio,qemu (DT) [ 10.380798] Call Trace: [ 10.381108] [] dump_backtrace+0x1c/0x24 [ 10.381690] [] show_stack+0x28/0x34 [ 10.381812] [] dump_stack_lvl+0x4a/0x68 [ 10.381958] [] dump_stack+0x14/0x1c [ 10.382047] [] __might_resched+0xfa/0x104 [ 10.382172] [] __might_sleep+0x42/0x66 [ 10.382267] [] __might_fault+0x1c/0x24 [ 10.382363] [] _copy_from_user+0x28/0xc2 [ 10.382459] [] handle_misaligned_load+0x1ca/0x2fc [ 10.382565] [] do_trap_load_misaligned+0x24/0xee [ 10.382714] [] handle_exception+0x146/0x152 In order to safely handle user memory access from this context, disable page fault while copying user memory. Although this might lead to copy failure in some cases (offlined page), this is the best we can try to be safe. While at it, replace __get_user by get_user() to actually check for memory before accessing it and disable fault. Fixes: b686ecdeacf6 ("riscv: misaligned: Restrict user access to kernel memory") Signed-off-by: Clément Léger --- V2: - Add pagefault disable/enable around get_user() arch/riscv/kernel/traps_misaligned.c | 30 +++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c index 7cc108aed74e..d9a6e44ae745 100644 --- a/arch/riscv/kernel/traps_misaligned.c +++ b/arch/riscv/kernel/traps_misaligned.c @@ -268,7 +268,9 @@ static unsigned long get_f32_rs(unsigned long insn, u8 fp_reg_offset, int __ret; \ \ if (user_mode(regs)) { \ - __ret = __get_user(insn, (type __user *) insn_addr); \ + pagefault_disable(); \ + __ret = get_user(insn, (type __user *) insn_addr); \ + pagefault_enable(); \ } else { \ insn = *(type *)insn_addr; \ __ret = 0; \ @@ -355,7 +357,7 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs) { union reg_data val; unsigned long epc = regs->epc; - unsigned long insn; + unsigned long insn, copy_len; unsigned long addr = regs->badaddr; int fp = 0, shift = 0, len = 0; @@ -441,7 +443,16 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs) val.data_u64 = 0; if (user_mode(regs)) { - if (copy_from_user(&val, (u8 __user *)addr, len)) + /* + * We can not sleep in exception context. Disable pagefault to + * avoid a potential sleep while accessing user memory. Side + * effect is that if it would have sleep, then the copy will + * fail. + */ + pagefault_disable(); + copy_len = copy_from_user(&val, (u8 __user *)addr, len); + pagefault_enable(); + if (copy_len) return -1; } else { memcpy(&val, (u8 *)addr, len); @@ -463,7 +474,7 @@ static int handle_scalar_misaligned_store(struct pt_regs *regs) { union reg_data val; unsigned long epc = regs->epc; - unsigned long insn; + unsigned long insn, copy_len; unsigned long addr = regs->badaddr; int len = 0, fp = 0; @@ -539,7 +550,16 @@ static int handle_scalar_misaligned_store(struct pt_regs *regs) return -EOPNOTSUPP; if (user_mode(regs)) { - if (copy_to_user((u8 __user *)addr, &val, len)) + /* + * We can not sleep in exception context. Disable pagefault to + * avoid a potential sleep while accessing user memory. Side + * effect is that if it would have sleep, then the copy will + * fail. + */ + pagefault_disable(); + copy_len = copy_to_user((u8 __user *)addr, &val, len); + pagefault_enable(); + if (copy_len) return -1; } else { memcpy((u8 *)addr, &val, len);