From patchwork Wed Mar 29 19:39:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Lehner X-Patchwork-Id: 13193161 X-Patchwork-Delegate: bpf@iogearbox.net 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 87F53C77B61 for ; Wed, 29 Mar 2023 19:41:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229940AbjC2Tkt (ORCPT ); Wed, 29 Mar 2023 15:40:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46210 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230353AbjC2Tkm (ORCPT ); Wed, 29 Mar 2023 15:40:42 -0400 Received: from mx.der-flo.net (mx.der-flo.net [193.160.39.236]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6CA0755A3 for ; Wed, 29 Mar 2023 12:40:40 -0700 (PDT) From: Florian Lehner To: bpf@vger.kernel.org Cc: x86@kernel.org, davem@davemloft.net, daniel@iogearbox.net, andrii@kernel.org, peterz@infradead.org, keescook@chromium.org, tglx@linutronix.de, hsinweih@uci.edu, rostedt@goodmis.org, vegard.nossum@oracle.com, gregkh@linuxfoundation.org, alan.maguire@oracle.com, dylany@meta.com, riel@surriel.com, kernel-team@fb.com, Alexei Starovoitov , Florian Lehner Subject: [RESUBMIT bpf-next 1/2] mm: Fix copy_from_user_nofault(). Date: Wed, 29 Mar 2023 21:39:32 +0200 Message-Id: <20230329193931.320642-2-dev@der-flo.net> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230329193931.320642-1-dev@der-flo.net> References: <20230329193931.320642-1-dev@der-flo.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net From: Alexei Starovoitov There are several issues with copy_from_user_nofault(): - access_ok() is designed for user context only and for that reason it has WARN_ON_IN_IRQ() which triggers when bpf, kprobe, eprobe and perf on ppc are calling it from irq. - it's missing nmi_uaccess_okay() which is a nop on all architectures except x86 where it's required. The comment in arch/x86/mm/tlb.c explains the details why it's necessary. Calling copy_from_user_nofault() from bpf, [ke]probe without this check is not safe. - __copy_from_user_inatomic() under CONFIG_HARDENED_USERCOPY is calling check_object_size()->__check_object_size()->check_heap_object()->find_vmap_area()->spin_lock() which is not safe to do from bpf, [ke]probe and perf due to potential deadlock. Fix all three issues. At the end the copy_from_user_nofault() becomes equivalent to copy_from_user_nmi() from safety point of view with a difference in the return value. Reported-by: Hsin-Wei Hung Signed-off-by: Alexei Starovoitov Tested-by: Hsin-Wei Hung Tested-by: Florian Lehner --- mm/maccess.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/mm/maccess.c b/mm/maccess.c index 074f6b086671..6ee9b337c501 100644 --- a/mm/maccess.c +++ b/mm/maccess.c @@ -5,6 +5,7 @@ #include #include #include +#include bool __weak copy_from_kernel_nofault_allowed(const void *unsafe_src, size_t size) @@ -113,11 +114,18 @@ long strncpy_from_kernel_nofault(char *dst, const void *unsafe_addr, long count) long copy_from_user_nofault(void *dst, const void __user *src, size_t size) { long ret = -EFAULT; - if (access_ok(src, size)) { - pagefault_disable(); - ret = __copy_from_user_inatomic(dst, src, size); - pagefault_enable(); - } + + if (!__access_ok(src, size)) + return ret; + + if (!nmi_uaccess_okay()) + return ret; + + pagefault_disable(); + instrument_copy_from_user_before(dst, src, size); + ret = raw_copy_from_user(dst, src, size); + instrument_copy_from_user_after(dst, src, size, ret); + pagefault_enable(); if (ret) return -EFAULT;