From patchwork Thu Dec 9 22:15:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12695538 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 4A00EC433EF for ; Thu, 9 Dec 2021 22:18:37 +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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=+HedJypEsy4hFwFjCAFHuqL0xSuCVLcQqfl1mcMjjUU=; b=4XRheIPoqTNUP+7XIS1Gh8TlJU XvD/MWjBfKalZqFBcHp2S3JIKaPnt+UTmi3rnITbo/8osxTLvYqC4EUWOVuljWQHoD90SjqAIiOjh wlKHr0s50WxF7BQVHHiXmWgzy4VbUcyZWeiiZy36IiEjWzogpbO4J0wnMXa8OjsJFRbKL7DhQzT/r x2hrWMqXa7C/ShgrpS5/ezLcllfYJLa+bGvAvJ2D1O8xOxbnP/zOi4RjbF8/8O9azLAuD3/ZJqTWs UqhrNb30lLqxC3kKymgsKYnEvmifzFJj2tIA2rprnHjJESUsNs/EZJ0r4kYatoLLKPhR1BupIcXrV RB20UOTQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRiX-000CYR-R0; Thu, 09 Dec 2021 22:16:47 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRhj-000CB4-V6 for linux-arm-kernel@lists.infradead.org; Thu, 09 Dec 2021 22:15:57 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id l28-20020a25b31c000000b005c27dd4987bso13014702ybj.18 for ; Thu, 09 Dec 2021 14:15:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=dwdgd8JweL+y6+nrXqZEHKOZ4Er9g7fAxzLKfl2roN8=; b=gdXEWqkFty7aXvoUbqtxrKuTbwrsUWyeKzBc/2qK05ncxkeU68IGN+z7CBSBSLhvq0 VSKZ5zuaZcR1YIagxQBuut2Z1O2JrZ0EYA/8DH5YHg6GIumsATva7EN7ZhQK7SVPg4zI B/jm3bOv5kZxpYfijvhqhh27odhS/YcaM02HZ31iiV7B46zKtsD4t+mz0JcFE0ajrOGR fC6aqvEfq4GxpxT5lvscXBoZSk5GHmZaUMF6Xhe+RQ/+JXgaZumiw9nurVXihAKKtdLm +Occtswm+rWEXKNqAKRP+rNrebfRZmBeaNNCo/NCqPoBWjlhaX/yMiwnSOuqhynp2Wgz Y81Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=dwdgd8JweL+y6+nrXqZEHKOZ4Er9g7fAxzLKfl2roN8=; b=NmL/4Tm7PuPcg1q/WjdRlD7fCRNckBOgr1MrKVwVE1sq7Ki9w2Bu1t973LEgjvqLwl kqIKSCYZ2/HqEL09ZJsMpg+yQ/lmnYZSrKIbwDYEahgkdU5tiNL69gtzqx9yWTIazr98 RlN6YxH6IqAIfIgcrmXsgn4zaApHkds2lV1d5u8xnocyJdWXpADY60V0+mvhmJDuxGvu PeNUFYBIPhVTtI7A59RYtRWeIhDoMnoSqP9kQeJbDzO7LwMzrUnUozwxQ4OTjIa3ijwN cpomkBOyOj23oQ9ZHmSeRlHKosNDD6xjiQuleOauvwNnyfllFXFwjq8TmgVLapxg5/dU ebAw== X-Gm-Message-State: AOAM530D93bDm0gK+4pl001XPGRpZeG7er3rQC/tTLeZBSnHSEZ2+4FB 9g2/QkjIVD2UDTCQUJUaI+BFcuA= X-Google-Smtp-Source: ABdhPJwKihBmfBMEk5ZMArBh1OYKiVcJoYUSS/GWhVtMWG2HAxD/AOhvEyywlKZX0yJ1PDn2dw6nRVI= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:f233:e324:8aa0:f65c]) (user=pcc job=sendgmr) by 2002:a25:8441:: with SMTP id r1mr9421270ybm.269.1639088154069; Thu, 09 Dec 2021 14:15:54 -0800 (PST) Date: Thu, 9 Dec 2021 14:15:38 -0800 In-Reply-To: <20211209221545.2333249-1-pcc@google.com> Message-Id: <20211209221545.2333249-2-pcc@google.com> Mime-Version: 1.0 References: <20211209221545.2333249-1-pcc@google.com> X-Mailer: git-send-email 2.34.1.173.g76aa8bc2d0-goog Subject: [PATCH v4 1/7] include: split out uaccess instrumentation into a separate header From: Peter Collingbourne To: Catalin Marinas , Will Deacon , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Thomas Gleixner , Andy Lutomirski , Kees Cook , Andrew Morton , Masahiro Yamada , Sami Tolvanen , YiFei Zhu , Mark Rutland , Frederic Weisbecker , Viresh Kumar , Andrey Konovalov , Peter Collingbourne , Gabriel Krisman Bertazi , Chris Hyser , Daniel Vetter , Chris Wilson , Arnd Bergmann , Dmitry Vyukov , Christian Brauner , "Eric W. Biederman" , Alexey Gladkov , Ran Xiaokai , David Hildenbrand , Xiaofeng Cao , Cyrill Gorcunov , Thomas Cedeno , Marco Elver , Alexander Potapenko Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Evgenii Stepanov X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211209_141556_077569_439F7168 X-CRM114-Status: GOOD ( 21.37 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org In an upcoming change we are going to add uaccess instrumentation that uses inline access to struct task_struct from the instrumentation routines. Because instrumentation.h is included from many places including (recursively) from sched.h this would otherwise lead to a circular dependency. Break the dependency by moving uaccess instrumentation routines into a separate header, instrumentation-uaccess.h. Link: https://linux-review.googlesource.com/id/I625728db0c8db374e13e4ebc54985ac5c79ace7d Signed-off-by: Peter Collingbourne Acked-by: Dmitry Vyukov Reviewed-by: Marco Elver --- include/linux/instrumented-uaccess.h | 49 ++++++++++++++++++++++++++++ include/linux/instrumented.h | 34 ------------------- include/linux/uaccess.h | 2 +- lib/iov_iter.c | 2 +- lib/usercopy.c | 2 +- 5 files changed, 52 insertions(+), 37 deletions(-) create mode 100644 include/linux/instrumented-uaccess.h diff --git a/include/linux/instrumented-uaccess.h b/include/linux/instrumented-uaccess.h new file mode 100644 index 000000000000..ece549088e50 --- /dev/null +++ b/include/linux/instrumented-uaccess.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * This header provides generic wrappers for memory access instrumentation for + * uaccess routines that the compiler cannot emit for: KASAN, KCSAN. + */ +#ifndef _LINUX_INSTRUMENTED_UACCESS_H +#define _LINUX_INSTRUMENTED_UACCESS_H + +#include +#include +#include +#include + +/** + * instrument_copy_to_user - instrument reads of copy_to_user + * + * Instrument reads from kernel memory, that are due to copy_to_user (and + * variants). The instrumentation must be inserted before the accesses. + * + * @to destination address + * @from source address + * @n number of bytes to copy + */ +static __always_inline void +instrument_copy_to_user(void __user *to, const void *from, unsigned long n) +{ + kasan_check_read(from, n); + kcsan_check_read(from, n); +} + +/** + * instrument_copy_from_user - instrument writes of copy_from_user + * + * Instrument writes to kernel memory, that are due to copy_from_user (and + * variants). The instrumentation should be inserted before the accesses. + * + * @to destination address + * @from source address + * @n number of bytes to copy + */ +static __always_inline void +instrument_copy_from_user(const void *to, const void __user *from, unsigned long n) +{ + kasan_check_write(to, n); + kcsan_check_write(to, n); +} + +#endif /* _LINUX_INSTRUMENTED_UACCESS_H */ diff --git a/include/linux/instrumented.h b/include/linux/instrumented.h index 42faebbaa202..b68f415510c7 100644 --- a/include/linux/instrumented.h +++ b/include/linux/instrumented.h @@ -102,38 +102,4 @@ static __always_inline void instrument_atomic_read_write(const volatile void *v, kcsan_check_atomic_read_write(v, size); } -/** - * instrument_copy_to_user - instrument reads of copy_to_user - * - * Instrument reads from kernel memory, that are due to copy_to_user (and - * variants). The instrumentation must be inserted before the accesses. - * - * @to destination address - * @from source address - * @n number of bytes to copy - */ -static __always_inline void -instrument_copy_to_user(void __user *to, const void *from, unsigned long n) -{ - kasan_check_read(from, n); - kcsan_check_read(from, n); -} - -/** - * instrument_copy_from_user - instrument writes of copy_from_user - * - * Instrument writes to kernel memory, that are due to copy_from_user (and - * variants). The instrumentation should be inserted before the accesses. - * - * @to destination address - * @from source address - * @n number of bytes to copy - */ -static __always_inline void -instrument_copy_from_user(const void *to, const void __user *from, unsigned long n) -{ - kasan_check_write(to, n); - kcsan_check_write(to, n); -} - #endif /* _LINUX_INSTRUMENTED_H */ diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index ac0394087f7d..c0c467e39657 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -3,7 +3,7 @@ #define __LINUX_UACCESS_H__ #include -#include +#include #include #include #include diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 66a740e6e153..3f9dc6df7102 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #define PIPE_PARANOIA /* for now */ diff --git a/lib/usercopy.c b/lib/usercopy.c index 7413dd300516..1cd188e62d06 100644 --- a/lib/usercopy.c +++ b/lib/usercopy.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include #include -#include +#include #include /* out-of-line parts */ From patchwork Thu Dec 9 22:15:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12695539 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 57886C433F5 for ; Thu, 9 Dec 2021 22:19:08 +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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=Sv4QYDMORBn1ukezHxlPKFhr8MX5tSCUe0qExvMKTyY=; b=4s7FDtOWFeoAqdamKMgB0/hwoq qiPBSygFzEM54bgi3SAVDgLmB9oVbp+J5s59IaeqUvqPAvy7uOgSVLIK27UWlENMaYZNk3rOEmqfO g/NTuj5tTVX1yKt0fSPfKqdggErcCuzeIkTg8rtdJ1YwimKZyxAIwNQZlhWg1eOpF7HuJsWa8tojZ WknpsZ2qOrS+LhwPnCIh+u1pf+W0DG7O3Oc3LcCguRXW5uXQsd0DJRQ2s4x/FXNHRulortrYeh+09 ll8vMBgO95ym7TpK8ESiuJni1U7/bBUbkYeJUk0kB61Th1Pwz5tLIypES1/Ux8E0ZRw2vq8v5e9xz 8epNlPbg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRj2-000Ckt-NG; Thu, 09 Dec 2021 22:17:16 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRhm-000CCl-BJ for linux-arm-kernel@lists.infradead.org; Thu, 09 Dec 2021 22:16:01 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id w5-20020a25ac05000000b005c55592df4dso13059311ybi.12 for ; Thu, 09 Dec 2021 14:15:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ms/p2WgZxfLdhQ0awNRscEai/vwdI6vlOsSGUuumRrg=; b=BrPLcYbp6EGYMLztyOzDR7bFXEF0Qo+k6vN6OrT5rfOwxbJKZa2gBDZtQvE7wSnY9g YrExwcTK+5XtSQEjHVUBWG29ZaT8eaZBSeEe+IvJQlApjCmH2pngpJ3OI7Jyzlt/f8mP DEyGE5j/YAU2hud4O9vPWuUGbaxQHP6xa8vhRNm9SAKPFqNf5RYhvCYD6au4Xky484Tc AcFI3lS3aiXFpGYze/INdAveeO3nnGtn4wVZt8Cebv5Nf9DyOJPvvvouTOyumzbS3FUS iANb6kuWxrVUy1gQ6zJBOQdX558N+XYQjDxP+f0eaIGcmIxCvCzWmyn0FA4MxruXhQE5 rE5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ms/p2WgZxfLdhQ0awNRscEai/vwdI6vlOsSGUuumRrg=; b=yeBIEU+CfJXRMzlkOqjtvZnD5ofqsDJCF4DXu9WX2HRyRCqbf6gN8O3jPxlvC926lP wM9xB+/vWuOWt8yY0tHkYH3IBLPTdp0ayjKkbP/kUe095FDvkDLNU077WTHw89AU5uey 0vYD3vSyuA/+t7Eeqy4L42r9E8ropkBFnX/3zu9+eeD/H58dWi3EMgzH09FKj+erGbB3 0tVBV1dpe3nUQpGo0VGOz+L/IzOO0CLEQdefSiQrISg6xfjTJ247E2LjuLyeQ2tdjltq sDA4i19ZS5GMiOInnb/h9MafhJQnY0eVwssrOLInfRIVTPgHz7zD2lWzfpS81zOQn5rk mHTw== X-Gm-Message-State: AOAM531duG8l7EyQ/OUPUplxb8SWPiSxOmuFXeD45QSg52HwzEmHtZDA GDrebr7k4HfRxh2PjqbKCJfQqes= X-Google-Smtp-Source: ABdhPJyqyiHi41Vk4YXXKQPH5IYG1GlVpiWRMyvO7l9CT3C5fU7yNqV+l/vYdOrvA4Tx+IgyH0OSQcc= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:f233:e324:8aa0:f65c]) (user=pcc job=sendgmr) by 2002:a25:c783:: with SMTP id w125mr9227505ybe.622.1639088156690; Thu, 09 Dec 2021 14:15:56 -0800 (PST) Date: Thu, 9 Dec 2021 14:15:39 -0800 In-Reply-To: <20211209221545.2333249-1-pcc@google.com> Message-Id: <20211209221545.2333249-3-pcc@google.com> Mime-Version: 1.0 References: <20211209221545.2333249-1-pcc@google.com> X-Mailer: git-send-email 2.34.1.173.g76aa8bc2d0-goog Subject: [PATCH v4 2/7] uaccess-buffer: add core code From: Peter Collingbourne To: Catalin Marinas , Will Deacon , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Thomas Gleixner , Andy Lutomirski , Kees Cook , Andrew Morton , Masahiro Yamada , Sami Tolvanen , YiFei Zhu , Mark Rutland , Frederic Weisbecker , Viresh Kumar , Andrey Konovalov , Peter Collingbourne , Gabriel Krisman Bertazi , Chris Hyser , Daniel Vetter , Chris Wilson , Arnd Bergmann , Dmitry Vyukov , Christian Brauner , "Eric W. Biederman" , Alexey Gladkov , Ran Xiaokai , David Hildenbrand , Xiaofeng Cao , Cyrill Gorcunov , Thomas Cedeno , Marco Elver , Alexander Potapenko Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Evgenii Stepanov X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211209_141558_468225_8E8693CD X-CRM114-Status: GOOD ( 36.92 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add the core code to support uaccess logging. Subsequent patches will hook this up to the arch-specific kernel entry and exit code for certain architectures. Link: https://linux-review.googlesource.com/id/I6581765646501a5631b281d670903945ebadc57d Signed-off-by: Peter Collingbourne Reviewed-by: Dmitry Vyukov --- v4: - add CONFIG_UACCESS_BUFFER - add kernel doc comments to uaccess-buffer.h - outline uaccess_buffer_set_descriptor_addr_addr - switch to using spin_lock_irqsave/spin_unlock_irqrestore during pre/post-exit-loop code because preemption is disabled at that point - set kend to NULL if krealloc failed - size_t -> unsigned long in copy_from_user_nolog signature v3: - performance optimizations for entry/exit code - don't use kcur == NULL to mean overflow - fix potential double free in clone() - don't allocate a new kernel-side uaccess buffer for each syscall - fix uaccess buffer leak on exit - fix some sparse warnings v2: - New interface that avoids multiple syscalls per real syscall and is arch-generic - Avoid logging uaccesses done by BPF programs - Add documentation - Split up into multiple patches - Various code moves, renames etc as requested by Marco arch/Kconfig | 13 +++ fs/exec.c | 3 + include/linux/instrumented-uaccess.h | 6 +- include/linux/sched.h | 5 + include/linux/uaccess-buffer-info.h | 46 ++++++++ include/linux/uaccess-buffer.h | 152 +++++++++++++++++++++++++++ include/uapi/linux/prctl.h | 3 + include/uapi/linux/uaccess-buffer.h | 27 +++++ kernel/Makefile | 1 + kernel/bpf/helpers.c | 7 +- kernel/fork.c | 4 + kernel/signal.c | 9 +- kernel/sys.c | 6 ++ kernel/uaccess-buffer.c | 145 +++++++++++++++++++++++++ 14 files changed, 422 insertions(+), 5 deletions(-) create mode 100644 include/linux/uaccess-buffer-info.h create mode 100644 include/linux/uaccess-buffer.h create mode 100644 include/uapi/linux/uaccess-buffer.h create mode 100644 kernel/uaccess-buffer.c diff --git a/arch/Kconfig b/arch/Kconfig index d3c4ab249e9c..17819f53ea80 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1312,6 +1312,19 @@ config ARCH_HAS_PARANOID_L1D_FLUSH config DYNAMIC_SIGFRAME bool +config HAVE_ARCH_UACCESS_BUFFER + bool + help + Select if the architecture's syscall entry/exit code supports uaccess buffers. + +config UACCESS_BUFFER + bool "Uaccess logging" if EXPERT + default y + depends on HAVE_ARCH_UACCESS_BUFFER + help + Select to enable support for uaccess logging + (see Documentation/admin-guide/uaccess-logging.rst). + source "kernel/gcov/Kconfig" source "scripts/gcc-plugins/Kconfig" diff --git a/fs/exec.c b/fs/exec.c index 537d92c41105..c9975e790f30 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -65,6 +65,7 @@ #include #include #include +#include #include #include @@ -1313,6 +1314,8 @@ int begin_new_exec(struct linux_binprm * bprm) me->personality &= ~bprm->per_clear; clear_syscall_work_syscall_user_dispatch(me); + uaccess_buffer_set_descriptor_addr_addr(0); + uaccess_buffer_free(current); /* * We have to apply CLOEXEC before we change whether the process is diff --git a/include/linux/instrumented-uaccess.h b/include/linux/instrumented-uaccess.h index ece549088e50..b967f4436d15 100644 --- a/include/linux/instrumented-uaccess.h +++ b/include/linux/instrumented-uaccess.h @@ -2,7 +2,8 @@ /* * This header provides generic wrappers for memory access instrumentation for - * uaccess routines that the compiler cannot emit for: KASAN, KCSAN. + * uaccess routines that the compiler cannot emit for: KASAN, KCSAN, + * uaccess buffers. */ #ifndef _LINUX_INSTRUMENTED_UACCESS_H #define _LINUX_INSTRUMENTED_UACCESS_H @@ -11,6 +12,7 @@ #include #include #include +#include /** * instrument_copy_to_user - instrument reads of copy_to_user @@ -27,6 +29,7 @@ instrument_copy_to_user(void __user *to, const void *from, unsigned long n) { kasan_check_read(from, n); kcsan_check_read(from, n); + uaccess_buffer_log_write(to, n); } /** @@ -44,6 +47,7 @@ instrument_copy_from_user(const void *to, const void __user *from, unsigned long { kasan_check_write(to, n); kcsan_check_write(to, n); + uaccess_buffer_log_read(from, n); } #endif /* _LINUX_INSTRUMENTED_UACCESS_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 78c351e35fec..96014dd2702e 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -34,6 +34,7 @@ #include #include #include +#include #include /* task_struct member predeclarations (sorted alphabetically): */ @@ -1484,6 +1485,10 @@ struct task_struct { struct callback_head l1d_flush_kill; #endif +#ifdef CONFIG_UACCESS_BUFFER + struct uaccess_buffer_info uaccess_buffer; +#endif + /* * New fields for task_struct should be added above here, so that * they are included in the randomized portion of task_struct. diff --git a/include/linux/uaccess-buffer-info.h b/include/linux/uaccess-buffer-info.h new file mode 100644 index 000000000000..46e2b1a4a20f --- /dev/null +++ b/include/linux/uaccess-buffer-info.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_UACCESS_BUFFER_INFO_H +#define _LINUX_UACCESS_BUFFER_INFO_H + +#ifdef CONFIG_UACCESS_BUFFER + +struct uaccess_buffer_info { + /* + * The pointer to pointer to struct uaccess_descriptor. This is the + * value controlled by prctl(PR_SET_UACCESS_DESCRIPTOR_ADDR_ADDR). + */ + struct uaccess_descriptor __user *__user *desc_ptr_ptr; + + /* + * The pointer to struct uaccess_descriptor read at syscall entry time. + */ + struct uaccess_descriptor __user *desc_ptr; + + /* + * A pointer to the kernel's temporary copy of the uaccess log for the + * current syscall. We log to a kernel buffer in order to avoid leaking + * timing information to userspace. + */ + struct uaccess_buffer_entry *kbegin; + + /* + * The position of the next uaccess buffer entry for the current + * syscall, or NULL if we are not logging the current syscall. + */ + struct uaccess_buffer_entry *kcur; + + /* + * A pointer to the end of the kernel's uaccess log. + */ + struct uaccess_buffer_entry *kend; + + /* + * The pointer to the userspace uaccess log, as read from the + * struct uaccess_descriptor. + */ + struct uaccess_buffer_entry __user *ubegin; +}; + +#endif + +#endif /* _LINUX_UACCESS_BUFFER_INFO_H */ diff --git a/include/linux/uaccess-buffer.h b/include/linux/uaccess-buffer.h new file mode 100644 index 000000000000..2e9b4010fb59 --- /dev/null +++ b/include/linux/uaccess-buffer.h @@ -0,0 +1,152 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_UACCESS_BUFFER_H +#define _LINUX_UACCESS_BUFFER_H + +#include +#include + +#include + +#ifdef CONFIG_UACCESS_BUFFER + +/* + * uaccess_buffer_maybe_blocked - returns whether a task potentially has signals + * blocked due to uaccess logging + * @tsk: the task. + */ +static inline bool uaccess_buffer_maybe_blocked(struct task_struct *tsk) +{ + return test_task_syscall_work(tsk, UACCESS_BUFFER_ENTRY); +} + +void __uaccess_buffer_syscall_entry(void); +/* + * uaccess_buffer_syscall_entry - hook to be run before syscall entry + */ +static inline void uaccess_buffer_syscall_entry(void) +{ + __uaccess_buffer_syscall_entry(); +} + +void __uaccess_buffer_syscall_exit(void); +/* + * uaccess_buffer_syscall_exit - hook to be run after syscall exit + */ +static inline void uaccess_buffer_syscall_exit(void) +{ + __uaccess_buffer_syscall_exit(); +} + +bool __uaccess_buffer_pre_exit_loop(void); +/* + * uaccess_buffer_pre_exit_loop - hook to be run immediately before the + * pre-kernel-exit loop that handles signals, tracing etc. Returns a bool to + * be passed to uaccess_buffer_post_exit_loop. + */ +static inline bool uaccess_buffer_pre_exit_loop(void) +{ + if (!test_syscall_work(UACCESS_BUFFER_ENTRY)) + return false; + return __uaccess_buffer_pre_exit_loop(); +} + +void __uaccess_buffer_post_exit_loop(void); +/* + * uaccess_buffer_post_exit_loop - hook to be run immediately after the + * pre-kernel-exit loop that handles signals, tracing etc. + * @pending: the bool returned from uaccess_buffer_pre_exit_loop. + */ +static inline void uaccess_buffer_post_exit_loop(bool pending) +{ + if (pending) + __uaccess_buffer_post_exit_loop(); +} + +/* + * uaccess_buffer_set_descriptor_addr_addr - implements + * prctl(PR_SET_UACCESS_DESCRIPTOR_ADDR_ADDR). + */ +int uaccess_buffer_set_descriptor_addr_addr(unsigned long addr); + +/* + * copy_from_user_nolog - a variant of copy_from_user that avoids uaccess + * logging. This is useful in special cases, such as when the kernel overreads a + * buffer. + * @to: the pointer to kernel memory. + * @from: the pointer to user memory. + * @len: the number of bytes to copy. + */ +unsigned long copy_from_user_nolog(void *to, const void __user *from, + unsigned long len); + +/* + * uaccess_buffer_free - free the task's kernel-side uaccess buffer and arrange + * for uaccess logging to be cancelled for the current syscall + * @tsk: the task. + */ +void uaccess_buffer_free(struct task_struct *tsk); + +void __uaccess_buffer_log_read(const void __user *from, unsigned long n); +/* + * uaccess_buffer_log_read - log a read access + * @from: the address of the access. + * @n: the number of bytes. + */ +static inline void uaccess_buffer_log_read(const void __user *from, unsigned long n) +{ + if (unlikely(test_syscall_work(UACCESS_BUFFER_EXIT))) + __uaccess_buffer_log_read(from, n); +} + +void __uaccess_buffer_log_write(void __user *to, unsigned long n); +/* + * uaccess_buffer_log_write - log a write access + * @to: the address of the access. + * @n: the number of bytes. + */ +static inline void uaccess_buffer_log_write(void __user *to, unsigned long n) +{ + if (unlikely(test_syscall_work(UACCESS_BUFFER_EXIT))) + __uaccess_buffer_log_write(to, n); +} + +#else + +static inline bool uaccess_buffer_maybe_blocked(struct task_struct *tsk) +{ + return false; +} +static inline void uaccess_buffer_syscall_entry(void) +{ +} +static inline void uaccess_buffer_syscall_exit(void) +{ +} +static inline bool uaccess_buffer_pre_exit_loop(void) +{ + return false; +} +static inline void uaccess_buffer_post_exit_loop(bool pending) +{ +} +static inline int uaccess_buffer_set_descriptor_addr_addr(unsigned long addr) +{ + return -EINVAL; +} +static inline void uaccess_buffer_free(struct task_struct *tsk) +{ +} + +#define copy_from_user_nolog copy_from_user + +static inline void uaccess_buffer_log_read(const void __user *from, + unsigned long n) +{ +} +static inline void uaccess_buffer_log_write(void __user *to, unsigned long n) +{ +} + +#endif + +#endif /* _LINUX_UACCESS_BUFFER_H */ diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index bb73e9a0b24f..74b37469c7b3 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h @@ -272,4 +272,7 @@ struct prctl_mm_map { # define PR_SCHED_CORE_SCOPE_THREAD_GROUP 1 # define PR_SCHED_CORE_SCOPE_PROCESS_GROUP 2 +/* Configure uaccess logging feature */ +#define PR_SET_UACCESS_DESCRIPTOR_ADDR_ADDR 63 + #endif /* _LINUX_PRCTL_H */ diff --git a/include/uapi/linux/uaccess-buffer.h b/include/uapi/linux/uaccess-buffer.h new file mode 100644 index 000000000000..bf10f7c78857 --- /dev/null +++ b/include/uapi/linux/uaccess-buffer.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_UACCESS_BUFFER_H +#define _UAPI_LINUX_UACCESS_BUFFER_H + +#include + +/* Location of the uaccess log. */ +struct uaccess_descriptor { + /* Address of the uaccess_buffer_entry array. */ + __u64 addr; + /* Size of the uaccess_buffer_entry array in number of elements. */ + __u64 size; +}; + +/* Format of the entries in the uaccess log. */ +struct uaccess_buffer_entry { + /* Address being accessed. */ + __u64 addr; + /* Number of bytes that were accessed. */ + __u64 size; + /* UACCESS_BUFFER_* flags. */ + __u64 flags; +}; + +#define UACCESS_BUFFER_FLAG_WRITE 1 /* access was a write */ + +#endif /* _UAPI_LINUX_UACCESS_BUFFER_H */ diff --git a/kernel/Makefile b/kernel/Makefile index 186c49582f45..e5f6c56696a2 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -114,6 +114,7 @@ obj-$(CONFIG_KCSAN) += kcsan/ obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o obj-$(CONFIG_HAVE_STATIC_CALL_INLINE) += static_call.o obj-$(CONFIG_CFI_CLANG) += cfi.o +obj-$(CONFIG_UACCESS_BUFFER) += uaccess-buffer.o obj-$(CONFIG_PERF_EVENTS) += events/ diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 649f07623df6..ab6520a633ef 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "../../lib/kstrtox.h" @@ -637,7 +638,11 @@ const struct bpf_func_proto bpf_event_output_data_proto = { BPF_CALL_3(bpf_copy_from_user, void *, dst, u32, size, const void __user *, user_ptr) { - int ret = copy_from_user(dst, user_ptr, size); + /* + * Avoid logging uaccesses here as the BPF program may not be following + * the uaccess log rules. + */ + int ret = copy_from_user_nolog(dst, user_ptr, size); if (unlikely(ret)) { memset(dst, 0, size); diff --git a/kernel/fork.c b/kernel/fork.c index 3244cc56b697..8be2ca528a65 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -96,6 +96,7 @@ #include #include #include +#include #include #include @@ -754,6 +755,7 @@ void __put_task_struct(struct task_struct *tsk) delayacct_tsk_free(tsk); put_signal_struct(tsk->signal); sched_core_free(tsk); + uaccess_buffer_free(tsk); if (!profile_handoff_task(tsk)) free_task(tsk); @@ -890,6 +892,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node) if (memcg_charge_kernel_stack(tsk)) goto free_stack; + uaccess_buffer_free(orig); + stack_vm_area = task_stack_vm_area(tsk); err = arch_dup_task_struct(tsk, orig); diff --git a/kernel/signal.c b/kernel/signal.c index a629b11bf3e0..b85d7d4844f6 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -45,6 +45,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -1031,7 +1032,8 @@ static void complete_signal(int sig, struct task_struct *p, enum pid_type type) if (sig_fatal(p, sig) && !(signal->flags & SIGNAL_GROUP_EXIT) && !sigismember(&t->real_blocked, sig) && - (sig == SIGKILL || !p->ptrace)) { + (sig == SIGKILL || + !(p->ptrace || uaccess_buffer_maybe_blocked(p)))) { /* * This signal will be fatal to the whole group. */ @@ -3027,6 +3029,7 @@ void set_current_blocked(sigset_t *newset) void __set_current_blocked(const sigset_t *newset) { struct task_struct *tsk = current; + unsigned long flags; /* * In case the signal mask hasn't changed, there is nothing we need @@ -3035,9 +3038,9 @@ void __set_current_blocked(const sigset_t *newset) if (sigequalsets(&tsk->blocked, newset)) return; - spin_lock_irq(&tsk->sighand->siglock); + spin_lock_irqsave(&tsk->sighand->siglock, flags); __set_task_blocked(tsk, newset); - spin_unlock_irq(&tsk->sighand->siglock); + spin_unlock_irqrestore(&tsk->sighand->siglock, flags); } /* diff --git a/kernel/sys.c b/kernel/sys.c index 8fdac0d90504..c71a9a9c0f68 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -2530,6 +2531,11 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, error = sched_core_share_pid(arg2, arg3, arg4, arg5); break; #endif + case PR_SET_UACCESS_DESCRIPTOR_ADDR_ADDR: + if (arg3 || arg4 || arg5) + return -EINVAL; + error = uaccess_buffer_set_descriptor_addr_addr(arg2); + break; default: error = -EINVAL; break; diff --git a/kernel/uaccess-buffer.c b/kernel/uaccess-buffer.c new file mode 100644 index 000000000000..d3129244b7d9 --- /dev/null +++ b/kernel/uaccess-buffer.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for uaccess logging via uaccess buffers. + * + * Copyright (C) 2021, Google LLC. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int uaccess_buffer_set_descriptor_addr_addr(unsigned long addr) +{ + current->uaccess_buffer.desc_ptr_ptr = + (struct uaccess_descriptor __user * __user *)addr; + if (addr) + set_syscall_work(UACCESS_BUFFER_ENTRY); + else + clear_syscall_work(UACCESS_BUFFER_ENTRY); + return 0; +} + +static void uaccess_buffer_log(unsigned long addr, unsigned long size, + unsigned long flags) +{ + struct uaccess_buffer_info *buf = ¤t->uaccess_buffer; + struct uaccess_buffer_entry *entry = buf->kcur; + + if (entry == buf->kend || unlikely(uaccess_kernel())) + return; + entry->addr = addr; + entry->size = size; + entry->flags = flags; + + ++buf->kcur; +} + +void __uaccess_buffer_log_read(const void __user *from, unsigned long n) +{ + uaccess_buffer_log((unsigned long)from, n, 0); +} +EXPORT_SYMBOL(__uaccess_buffer_log_read); + +void __uaccess_buffer_log_write(void __user *to, unsigned long n) +{ + uaccess_buffer_log((unsigned long)to, n, UACCESS_BUFFER_FLAG_WRITE); +} +EXPORT_SYMBOL(__uaccess_buffer_log_write); + +bool __uaccess_buffer_pre_exit_loop(void) +{ + struct uaccess_buffer_info *buf = ¤t->uaccess_buffer; + struct uaccess_descriptor __user *desc_ptr; + sigset_t tmp_mask; + + if (get_user(desc_ptr, buf->desc_ptr_ptr) || !desc_ptr) + return false; + + current->real_blocked = current->blocked; + sigfillset(&tmp_mask); + set_current_blocked(&tmp_mask); + return true; +} + +void __uaccess_buffer_post_exit_loop(void) +{ + unsigned long flags; + + spin_lock_irqsave(¤t->sighand->siglock, flags); + current->blocked = current->real_blocked; + recalc_sigpending(); + spin_unlock_irqrestore(¤t->sighand->siglock, flags); +} + +void uaccess_buffer_free(struct task_struct *tsk) +{ + struct uaccess_buffer_info *buf = &tsk->uaccess_buffer; + + kfree(buf->kbegin); + clear_syscall_work(UACCESS_BUFFER_EXIT); + buf->kbegin = buf->kcur = buf->kend = NULL; +} + +void __uaccess_buffer_syscall_entry(void) +{ + struct uaccess_buffer_info *buf = ¤t->uaccess_buffer; + struct uaccess_descriptor desc; + + if (get_user(buf->desc_ptr, buf->desc_ptr_ptr) || !buf->desc_ptr || + put_user(0, buf->desc_ptr_ptr) || + copy_from_user(&desc, buf->desc_ptr, sizeof(desc))) + return; + + if (desc.size > 1024) + desc.size = 1024; + + if (buf->kend - buf->kbegin != desc.size) + buf->kbegin = + krealloc_array(buf->kbegin, desc.size, + sizeof(struct uaccess_buffer_entry), + GFP_KERNEL); + if (!buf->kbegin) { + buf->kend = NULL; + return; + } + + set_syscall_work(UACCESS_BUFFER_EXIT); + buf->kcur = buf->kbegin; + buf->kend = buf->kbegin + desc.size; + buf->ubegin = + (struct uaccess_buffer_entry __user *)(unsigned long)desc.addr; +} + +void __uaccess_buffer_syscall_exit(void) +{ + struct uaccess_buffer_info *buf = ¤t->uaccess_buffer; + u64 num_entries = buf->kcur - buf->kbegin; + struct uaccess_descriptor desc; + + clear_syscall_work(UACCESS_BUFFER_EXIT); + desc.addr = (u64)(unsigned long)(buf->ubegin + num_entries); + desc.size = buf->kend - buf->kcur; + buf->kcur = NULL; + if (copy_to_user(buf->ubegin, buf->kbegin, + num_entries * sizeof(struct uaccess_buffer_entry)) == 0) + (void)copy_to_user(buf->desc_ptr, &desc, sizeof(desc)); +} + +unsigned long copy_from_user_nolog(void *to, const void __user *from, + unsigned long len) +{ + size_t retval; + + clear_syscall_work(UACCESS_BUFFER_EXIT); + retval = copy_from_user(to, from, len); + if (current->uaccess_buffer.kcur) + set_syscall_work(UACCESS_BUFFER_EXIT); + return retval; +} From patchwork Thu Dec 9 22:15:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12695540 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 16A24C433EF for ; Thu, 9 Dec 2021 22:19:46 +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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=LIpbf4xks1263c1W+VIAbLKOVR+PSQmQg5mefW+J7qY=; b=EQwSkdzXy627X+eaC7ptJKkyr6 Ec2S5AaqkrojTsSSoK/0u7PpexfQQeu+GL04J3gRJKoGrHMK+D0vvTC/ppdsRvCHpUcp4Ag9uoDA9 u3OvkHysYTaReJnnpT18f3Y6LAoqwpphd86ntnUq/Eb/ZuWEqg3fuoQLg6v30uUkM0JC1QmSLoQiK Fze3V1m3EHqPRAIsyMJ0OQ24i0PL6VG1EFHAFmbvNGYn0UTZgxMteUvgvbGK/3dyBoDGpuf2bXUVX UjphOjtwZzeN6BxDEJMyk/jRvT96COUbCKgD34FdW7v6FCqBfOenxzXwiZQxjjIzfL4tWQLZectz+ pXj/Xdzg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRjc-000CxZ-49; Thu, 09 Dec 2021 22:17:53 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRho-000CEI-UM for linux-arm-kernel@lists.infradead.org; Thu, 09 Dec 2021 22:16:03 +0000 Received: by mail-yb1-xb49.google.com with SMTP id t184-20020a2546c1000000b006008b13c80bso13101390yba.1 for ; Thu, 09 Dec 2021 14:16:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=lvYZWOMBGv2NvliGw5NO73inoVaqmyrZ+UqoCCa0Q2o=; b=RBkhEsB+TbqqkjEQx0sTwY/WeLY8qK5nIYs2MlLm587GOQtU6tH2jLBjfNSfmQygGx zlM08TUHCXig93/AlPkh86J8IU121WX91ikxAxAifMyCadcKe0qGkYAbMIraB7cMQJBl D73vY9NfXIJtTiBSDX918WyqpNAoRMfYSdcgsLrU0RBCeAsVlYe+UswtS0v7Qi3WCRuW LbeH1movF+a4mvzT00Q5OX7RQj9p0XtpeqTSrezLTlmbwdIbIbH5P4pfB13mZyu/ndoB oSm6FL54nBMhmxUN5vKhXoBExhbQQL7Tg7G358TrSDJnLZVC4KKeI3rqw4rnp9W+oqKD H0cQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=lvYZWOMBGv2NvliGw5NO73inoVaqmyrZ+UqoCCa0Q2o=; b=lxeIiiEBCoEu0qcWTmOIl89VPmP6MypRW2k7esB6V/UONh8xl2zHV+1hz3xeNpYy2R z9fsUsWb6HoHUig+Y2iu9SAvu0s1N4Lx9zocJL450kHQ1+y9fVvPpHqtTmTUu9r5At86 w/PZ3f+rwzxCiCrsGwETpwLK6Dxk0RFIhcwGduDIqlbBrubE1E9pBQ/5Mfky2h3XdL4Q KyijJI5DuoTj0Eiy3Q3MyQomClyj8MjG1798l2jb0DM+ScpGlszI3CamhViscx1BptKZ SWg0SYt8pf6F+3poln1NsBISKuMggrNZk61YZ2m7KRegRS3iD1cgbNjbzkhLpSUj0z7p EAaA== X-Gm-Message-State: AOAM530zQEDhuJYtXpxJGUWE9JwWDAOsW6OCOjBSQ+APn51uyOLbk/hE n11lefeFUpkrg2FDXByiQySPMec= X-Google-Smtp-Source: ABdhPJx7kPyMgfW98vbLG5bioLn4OfDFvxhzabv0RoREjBxyeXyYuIbfyTNmHSJpFQm+bDPS9Vkfirk= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:f233:e324:8aa0:f65c]) (user=pcc job=sendgmr) by 2002:a25:b2a6:: with SMTP id k38mr10316854ybj.122.1639088159255; Thu, 09 Dec 2021 14:15:59 -0800 (PST) Date: Thu, 9 Dec 2021 14:15:40 -0800 In-Reply-To: <20211209221545.2333249-1-pcc@google.com> Message-Id: <20211209221545.2333249-4-pcc@google.com> Mime-Version: 1.0 References: <20211209221545.2333249-1-pcc@google.com> X-Mailer: git-send-email 2.34.1.173.g76aa8bc2d0-goog Subject: [PATCH v4 3/7] fs: use copy_from_user_nolog() to copy mount() data From: Peter Collingbourne To: Catalin Marinas , Will Deacon , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Thomas Gleixner , Andy Lutomirski , Kees Cook , Andrew Morton , Masahiro Yamada , Sami Tolvanen , YiFei Zhu , Mark Rutland , Frederic Weisbecker , Viresh Kumar , Andrey Konovalov , Peter Collingbourne , Gabriel Krisman Bertazi , Chris Hyser , Daniel Vetter , Chris Wilson , Arnd Bergmann , Dmitry Vyukov , Christian Brauner , "Eric W. Biederman" , Alexey Gladkov , Ran Xiaokai , David Hildenbrand , Xiaofeng Cao , Cyrill Gorcunov , Thomas Cedeno , Marco Elver , Alexander Potapenko Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Evgenii Stepanov X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211209_141601_022433_D6419FFF X-CRM114-Status: GOOD ( 18.76 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org With uaccess logging the contract is that the kernel must not report accessing more data than necessary, as this can lead to false positive reports in downstream consumers. This generally works out of the box when instrumenting copy_{from,to}_user(), but with the data argument to mount() we use copy_from_user() to copy PAGE_SIZE bytes (or as much as we can, if the PAGE_SIZE sized access failed) and figure out later how much we actually need. To prevent this from leading to a false positive report, use copy_from_user_nolog(), which will prevent the access from being logged. Recall that it is valid for the kernel to report accessing less data than it actually accessed, as uaccess logging is a best-effort mechanism for reporting uaccesses. Link: https://linux-review.googlesource.com/id/I5629b92a725c817acd9a861288338dd605cafee6 Signed-off-by: Peter Collingbourne --- fs/namespace.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/fs/namespace.c b/fs/namespace.c index 659a8f39c61a..8f5f2aaca64e 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "pnode.h" #include "internal.h" @@ -3197,7 +3198,12 @@ static void *copy_mount_options(const void __user * data) if (!copy) return ERR_PTR(-ENOMEM); - left = copy_from_user(copy, data, PAGE_SIZE); + /* + * Use copy_from_user_nolog to avoid reporting overly large accesses in + * the uaccess buffer, as this can lead to false positive reports in + * downstream consumers. + */ + left = copy_from_user_nolog(copy, data, PAGE_SIZE); /* * Not all architectures have an exact copy_from_user(). Resort to From patchwork Thu Dec 9 22:15:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12695541 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 03CE1C433F5 for ; Thu, 9 Dec 2021 22:21:05 +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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=fjY3xoWeEErXxsCyOc8dbuD1oZXpkYjPf0jJyBRuu8Q=; b=Eu1c7S1Sv/0nN5bypK4j1Wr++4 IAn4IpdwcH0Qsumclw0rM048WqCywtzG7aiu6btwGspLRsGYGay3YvOrKtl6B8Ks0eAWjTMFHTiIF WSm/Ql4Gc51nINiwl16OdZzoBz5sfvWPoXQArsKx7pkRup14cgjz5VWmuKysCwVswdU2/ivLqPku0 aevlcJv15AKU1S5UykLnUtLXnMZesUbWySkv0mu3liWxilwcWJB+xfpstwRKkm6LD//2PsfKN460/ aM6WzRSpnXEGDoV2QyomaohFQOgRhGjlK6/RIJaMXtSGd5whhTu05tSKXiIsbABEQ7Tq1mlhHFBQo Zx+qMvkg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRkS-000DHe-Sg; Thu, 09 Dec 2021 22:18:47 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRhr-000CFQ-9x for linux-arm-kernel@lists.infradead.org; Thu, 09 Dec 2021 22:16:05 +0000 Received: by mail-yb1-xb49.google.com with SMTP id s189-20020a252cc6000000b005c1f206d91eso12985009ybs.14 for ; Thu, 09 Dec 2021 14:16:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=FqrxnquBZTtko9BgXrPYz8OM9HQeZt54ZJSaNv8spPQ=; b=jQlgqpqABmoSDMhC0f6Qnl7fD27iyQFDbN5T3LT3Lqxa6lEVdKbUcNYfBhPXkY45rU BXcZKwud2NUlWZ3kU1dYlexeBjY51JW4XuxO2VAWGDwDv8LZfKHrHvAwxW6I77JxMoek TpP2g0OWY8LDi4kr05Sj8id/av85FV+Dd2QpNlGmPpBI5o6HrF9GPUlPWjrW8crWSEVq 8vK3/T7G/GLj0fOEsDL11ZAldUawwtlrUjC3Rb9PrFBlAXnxQCRK9aLzK8TQQTMI/EJq Ih86fCRJuVBphQCEWO4vHu+S/JhBEHf8M9Nd1VnQrbXIInApfvisvBMyZE+kCod1MAqJ AnKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=FqrxnquBZTtko9BgXrPYz8OM9HQeZt54ZJSaNv8spPQ=; b=Z/4EybrTh7gwCeCZnTFQHQ6JQF0OwMXC30tqi523BLzXGhmzy8zhOIAaTWQDqkgKF5 +wR4wbDmsn9VT+BP8ZI0oRmVlM25/xdvcPbVH4cLloNDsl4qtRUOqhsHx2OXOcRFxrEN obxIH3GkXoYTm5djJryc+zm/oBgIB9VkF3AlmFwGFYdWPktcGuopvRk5ahsn3flq4gZz jjTH5p++sAb5bMcQjjsra3jbAf98xk4JY1gphA7xPDVb6EHJ1FJwp3EMTmVPukcs3d+6 /uV4OYINdeOqEwfNqyo/2v5U0AHIfvDZiMBSOqbG0gVyvRZ/78dAZ55wHeQZ8SndHO+6 lLAw== X-Gm-Message-State: AOAM532qgGld9x9xWdP634jxUcsUOq2WIWEdoY6hSNJVO+jzBLF/YU7f bZ8Y6TZh26aJ5SYKLuSaur1g1og= X-Google-Smtp-Source: ABdhPJz7A/DINf05BcsrLAG8T6qlShSq6crx7l0ZreU7rhk+PSIj2ScgiWw65k8/EeZ03uva6ksbsbA= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:f233:e324:8aa0:f65c]) (user=pcc job=sendgmr) by 2002:a25:69c1:: with SMTP id e184mr9817470ybc.235.1639088161742; Thu, 09 Dec 2021 14:16:01 -0800 (PST) Date: Thu, 9 Dec 2021 14:15:41 -0800 In-Reply-To: <20211209221545.2333249-1-pcc@google.com> Message-Id: <20211209221545.2333249-5-pcc@google.com> Mime-Version: 1.0 References: <20211209221545.2333249-1-pcc@google.com> X-Mailer: git-send-email 2.34.1.173.g76aa8bc2d0-goog Subject: [PATCH v4 4/7] uaccess-buffer: add CONFIG_GENERIC_ENTRY support From: Peter Collingbourne To: Catalin Marinas , Will Deacon , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Thomas Gleixner , Andy Lutomirski , Kees Cook , Andrew Morton , Masahiro Yamada , Sami Tolvanen , YiFei Zhu , Mark Rutland , Frederic Weisbecker , Viresh Kumar , Andrey Konovalov , Peter Collingbourne , Gabriel Krisman Bertazi , Chris Hyser , Daniel Vetter , Chris Wilson , Arnd Bergmann , Dmitry Vyukov , Christian Brauner , "Eric W. Biederman" , Alexey Gladkov , Ran Xiaokai , David Hildenbrand , Xiaofeng Cao , Cyrill Gorcunov , Thomas Cedeno , Marco Elver , Alexander Potapenko Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Evgenii Stepanov X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211209_141603_499294_C3D13CD7 X-CRM114-Status: GOOD ( 17.77 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add uaccess logging support on architectures that use CONFIG_GENERIC_ENTRY (currently only s390 and x86). Link: https://linux-review.googlesource.com/id/I3c5eb19a7e4a1dbe6095f6971f7826c4b0663f7d Signed-off-by: Peter Collingbourne Acked-by: Dmitry Vyukov --- v4: - move pre/post-exit-loop calls into if statement arch/Kconfig | 1 + include/linux/entry-common.h | 2 ++ include/linux/thread_info.h | 4 ++++ kernel/entry/common.c | 14 +++++++++++++- 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/Kconfig b/arch/Kconfig index 17819f53ea80..bc849a61b636 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -31,6 +31,7 @@ config HOTPLUG_SMT bool config GENERIC_ENTRY + select HAVE_ARCH_UACCESS_BUFFER bool config KPROBES diff --git a/include/linux/entry-common.h b/include/linux/entry-common.h index 2e2b8d6140ed..973fcd1d48a3 100644 --- a/include/linux/entry-common.h +++ b/include/linux/entry-common.h @@ -42,12 +42,14 @@ SYSCALL_WORK_SYSCALL_EMU | \ SYSCALL_WORK_SYSCALL_AUDIT | \ SYSCALL_WORK_SYSCALL_USER_DISPATCH | \ + SYSCALL_WORK_UACCESS_BUFFER_ENTRY | \ ARCH_SYSCALL_WORK_ENTER) #define SYSCALL_WORK_EXIT (SYSCALL_WORK_SYSCALL_TRACEPOINT | \ SYSCALL_WORK_SYSCALL_TRACE | \ SYSCALL_WORK_SYSCALL_AUDIT | \ SYSCALL_WORK_SYSCALL_USER_DISPATCH | \ SYSCALL_WORK_SYSCALL_EXIT_TRAP | \ + SYSCALL_WORK_UACCESS_BUFFER_EXIT | \ ARCH_SYSCALL_WORK_EXIT) /* diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index ad0c4e041030..b0f8ea86967f 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -46,6 +46,8 @@ enum syscall_work_bit { SYSCALL_WORK_BIT_SYSCALL_AUDIT, SYSCALL_WORK_BIT_SYSCALL_USER_DISPATCH, SYSCALL_WORK_BIT_SYSCALL_EXIT_TRAP, + SYSCALL_WORK_BIT_UACCESS_BUFFER_ENTRY, + SYSCALL_WORK_BIT_UACCESS_BUFFER_EXIT, }; #define SYSCALL_WORK_SECCOMP BIT(SYSCALL_WORK_BIT_SECCOMP) @@ -55,6 +57,8 @@ enum syscall_work_bit { #define SYSCALL_WORK_SYSCALL_AUDIT BIT(SYSCALL_WORK_BIT_SYSCALL_AUDIT) #define SYSCALL_WORK_SYSCALL_USER_DISPATCH BIT(SYSCALL_WORK_BIT_SYSCALL_USER_DISPATCH) #define SYSCALL_WORK_SYSCALL_EXIT_TRAP BIT(SYSCALL_WORK_BIT_SYSCALL_EXIT_TRAP) +#define SYSCALL_WORK_UACCESS_BUFFER_ENTRY BIT(SYSCALL_WORK_BIT_UACCESS_BUFFER_ENTRY) +#define SYSCALL_WORK_UACCESS_BUFFER_EXIT BIT(SYSCALL_WORK_BIT_UACCESS_BUFFER_EXIT) #endif #include diff --git a/kernel/entry/common.c b/kernel/entry/common.c index d5a61d565ad5..59ec6e3f793b 100644 --- a/kernel/entry/common.c +++ b/kernel/entry/common.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "common.h" @@ -70,6 +71,9 @@ static long syscall_trace_enter(struct pt_regs *regs, long syscall, return ret; } + if (work & SYSCALL_WORK_UACCESS_BUFFER_ENTRY) + uaccess_buffer_syscall_entry(); + /* Either of the above might have changed the syscall number */ syscall = syscall_get_nr(current, regs); @@ -197,14 +201,19 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs, static void exit_to_user_mode_prepare(struct pt_regs *regs) { unsigned long ti_work = READ_ONCE(current_thread_info()->flags); + bool uaccess_buffer_pending; lockdep_assert_irqs_disabled(); /* Flush pending rcuog wakeup before the last need_resched() check */ tick_nohz_user_enter_prepare(); - if (unlikely(ti_work & EXIT_TO_USER_MODE_WORK)) + if (unlikely(ti_work & EXIT_TO_USER_MODE_WORK)) { + bool uaccess_buffer_pending = uaccess_buffer_pre_exit_loop(); + ti_work = exit_to_user_mode_loop(regs, ti_work); + uaccess_buffer_post_exit_loop(uaccess_buffer_pending); + } arch_exit_to_user_mode_prepare(regs, ti_work); @@ -247,6 +256,9 @@ static void syscall_exit_work(struct pt_regs *regs, unsigned long work) audit_syscall_exit(regs); + if (work & SYSCALL_WORK_UACCESS_BUFFER_EXIT) + uaccess_buffer_syscall_exit(); + if (work & SYSCALL_WORK_SYSCALL_TRACEPOINT) trace_sys_exit(regs, syscall_get_return_value(current, regs)); From patchwork Thu Dec 9 22:15:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12695542 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 3C1B1C433EF for ; Thu, 9 Dec 2021 22:21:27 +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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=BZEs0VkV8e1BC9dCA+amuZ0qCN2QgSAwgOmD9g2ydHQ=; b=4aL1nL0L4fkk1fofS3UeebrJqm t+s6Eg2bPh3rtwBkmfdljAROnJ3uHYT7PBvY1+huJ1lN990U3hxM6ohC+vlRBOJABZNmPZ4bZZLwz lRHRwIcnrGk3fnuNF/GHZOD+DUO6JUKCdJ+OakqzpRjf/vBfXx8YNk6Cr7ssvD76FSXGPz+J5aOC3 GRVbchBxWDAOjP5tgi5YcusNpbHcn4mHlxy5f6iUKWHusSViLSj8Jp/YUvmvR3AFnfwgxNdM5gtyR XuM3LJ21CZ/rdgv/GXCcjKoZS4Hxo+seB7Uciqbuuw5XxeJILnpX1HDhuivevOrIFYr6waqOArQuR dWWpPVZA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRlE-000Dal-Ar; Thu, 09 Dec 2021 22:19:32 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRht-000CGf-TU for linux-arm-kernel@lists.infradead.org; Thu, 09 Dec 2021 22:16:07 +0000 Received: by mail-yb1-xb49.google.com with SMTP id b15-20020a25ae8f000000b005c20f367790so13096875ybj.2 for ; Thu, 09 Dec 2021 14:16:05 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=iFPytGgCXAEsrjhrGa1Z7QyY9naeGPAt+mdu0JuwAhY=; b=aC5AbIgBtCmBOawnf8+Eu9jc/bHGwEECFebeAmn2zdnC6Drn0OG23esT8abGXFQWxC H0gki52Fna1A0H8wcYimsMqdI0gqDnXdLkzPX/dKG5/Cz4bCKMQ7FIdvCCIgto3W4Ubt +eP5iKIkPwOPWks6BsYoZAzWGSUfbBaywd9e86i6IRvOSewWF5OC6qE5NoR/HGEyo/co 3E1teh7iFX2s+iEx41c/nuWXV3pWkAIhNjme6edBnF1SNthNRuHvEqzP/Q1TCPaGiqVj LxSmrIv0CI08iGHkxQSZFk3vxxsfsoG0xDAyqVr1SU3r8e5QFRBOkHfeQ8axygz34ptU JDgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=iFPytGgCXAEsrjhrGa1Z7QyY9naeGPAt+mdu0JuwAhY=; b=gYftmV/Yg+UU3X4yrwoaCSdcp8Tqh/nQ8WJmtX/LPm4bZfDKJkSmzPsOdt3VbxFfDn Vkj/nQLZByspAiRpDT1/Km8PE+x+Z4lWLQHOBetMb4GIeIGvZjZPk4L0CA0lPCIiglbG tmRMAQRQou6J1E2dATqPcWKopX27fkPL4eAGaNYGnPsLOCQIAvW+0FExX4xhtWrFwrM/ zdt9KeGr2Vivtk9jSg3/LCn/wvjIrMKJueeXEUffu+bvZS8KZed9Osa5yKHN0FFQBDwI F/P32hXGR9tRzKz7v2x3TAHlvElOY/i5Gl9kXHOQAz95KegqQ+5uGYLclNdvdfdBjZ4S fxvg== X-Gm-Message-State: AOAM531yd/DYQgyMnUX3YVWvmnW56rnNuW6uCo39UVtsrzyhn5CWKBIH ePrJyHzMTbgGWlPtSaMxV1iRJWk= X-Google-Smtp-Source: ABdhPJyYB7QYl/yNNSsx3aR3SNfH5iv+4KL2+UlKSeyCz8qdnjzt+Wi/BubxQn+H7Z/MMSL25Tc7YX0= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:f233:e324:8aa0:f65c]) (user=pcc job=sendgmr) by 2002:a25:c789:: with SMTP id w131mr9854631ybe.227.1639088164465; Thu, 09 Dec 2021 14:16:04 -0800 (PST) Date: Thu, 9 Dec 2021 14:15:42 -0800 In-Reply-To: <20211209221545.2333249-1-pcc@google.com> Message-Id: <20211209221545.2333249-6-pcc@google.com> Mime-Version: 1.0 References: <20211209221545.2333249-1-pcc@google.com> X-Mailer: git-send-email 2.34.1.173.g76aa8bc2d0-goog Subject: [PATCH v4 5/7] arm64: add support for uaccess logging From: Peter Collingbourne To: Catalin Marinas , Will Deacon , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Thomas Gleixner , Andy Lutomirski , Kees Cook , Andrew Morton , Masahiro Yamada , Sami Tolvanen , YiFei Zhu , Mark Rutland , Frederic Weisbecker , Viresh Kumar , Andrey Konovalov , Peter Collingbourne , Gabriel Krisman Bertazi , Chris Hyser , Daniel Vetter , Chris Wilson , Arnd Bergmann , Dmitry Vyukov , Christian Brauner , "Eric W. Biederman" , Alexey Gladkov , Ran Xiaokai , David Hildenbrand , Xiaofeng Cao , Cyrill Gorcunov , Thomas Cedeno , Marco Elver , Alexander Potapenko Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Evgenii Stepanov X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211209_141605_986034_8303943E X-CRM114-Status: GOOD ( 18.41 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org arm64 does not use CONFIG_GENERIC_ENTRY, so add the support for uaccess logging directly to the architecture. Link: https://linux-review.googlesource.com/id/I88de539fb9c4a9d27fa8cccbe201a6e4382faf89 Signed-off-by: Peter Collingbourne --- v4: - remove unnecessary hunk arch/arm64/Kconfig | 1 + arch/arm64/include/asm/thread_info.h | 7 ++++++- arch/arm64/kernel/ptrace.c | 7 +++++++ arch/arm64/kernel/signal.c | 5 +++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index c4207cf9bb17..6023946abe4a 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -161,6 +161,7 @@ config ARM64 select HAVE_ARCH_THREAD_STRUCT_WHITELIST select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRANSPARENT_HUGEPAGE + select HAVE_ARCH_UACCESS_BUFFER select HAVE_ARCH_VMAP_STACK select HAVE_ARM_SMCCC select HAVE_ASM_MODVERSIONS diff --git a/arch/arm64/include/asm/thread_info.h b/arch/arm64/include/asm/thread_info.h index e1317b7c4525..0461b36251ea 100644 --- a/arch/arm64/include/asm/thread_info.h +++ b/arch/arm64/include/asm/thread_info.h @@ -82,6 +82,8 @@ int arch_dup_task_struct(struct task_struct *dst, #define TIF_SVE_VL_INHERIT 24 /* Inherit SVE vl_onexec across exec */ #define TIF_SSBD 25 /* Wants SSB mitigation */ #define TIF_TAGGED_ADDR 26 /* Allow tagged user addresses */ +#define TIF_UACCESS_BUFFER_ENTRY 27 /* thread has non-zero uaccess_desc_addr_addr */ +#define TIF_UACCESS_BUFFER_EXIT 28 /* thread has non-zero kcur */ #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) @@ -98,6 +100,8 @@ int arch_dup_task_struct(struct task_struct *dst, #define _TIF_SVE (1 << TIF_SVE) #define _TIF_MTE_ASYNC_FAULT (1 << TIF_MTE_ASYNC_FAULT) #define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) +#define _TIF_UACCESS_BUFFER_ENTRY (1 << TIF_UACCESS_BUFFER_ENTRY) +#define _TIF_UACCESS_BUFFER_EXIT (1 << TIF_UACCESS_BUFFER_EXIT) #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \ @@ -106,7 +110,8 @@ int arch_dup_task_struct(struct task_struct *dst, #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \ _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \ - _TIF_SYSCALL_EMU) + _TIF_SYSCALL_EMU | _TIF_UACCESS_BUFFER_ENTRY | \ + _TIF_UACCESS_BUFFER_EXIT) #ifdef CONFIG_SHADOW_CALL_STACK #define INIT_SCS \ diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 88a9034fb9b5..283372eccaeb 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -1854,6 +1855,9 @@ int syscall_trace_enter(struct pt_regs *regs) if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) trace_sys_enter(regs, regs->syscallno); + if (flags & _TIF_UACCESS_BUFFER_ENTRY) + uaccess_buffer_syscall_entry(); + audit_syscall_entry(regs->syscallno, regs->orig_x0, regs->regs[1], regs->regs[2], regs->regs[3]); @@ -1866,6 +1870,9 @@ void syscall_trace_exit(struct pt_regs *regs) audit_syscall_exit(regs); + if (flags & _TIF_UACCESS_BUFFER_EXIT) + uaccess_buffer_syscall_exit(); + if (flags & _TIF_SYSCALL_TRACEPOINT) trace_sys_exit(regs, syscall_get_return_value(current, regs)); diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 8f6372b44b65..5bbd98e5c257 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -919,6 +920,8 @@ static void do_signal(struct pt_regs *regs) void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags) { + bool uaccess_buffer_pending = uaccess_buffer_pre_exit_loop(); + do { if (thread_flags & _TIF_NEED_RESCHED) { /* Unmask Debug and SError for the next task */ @@ -950,6 +953,8 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags) local_daif_mask(); thread_flags = READ_ONCE(current_thread_info()->flags); } while (thread_flags & _TIF_WORK_MASK); + + uaccess_buffer_post_exit_loop(uaccess_buffer_pending); } unsigned long __ro_after_init signal_minsigstksz; From patchwork Thu Dec 9 22:15:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12695543 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 B37AEC433F5 for ; Thu, 9 Dec 2021 22:22:22 +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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=bfSTcTA3Q0izeT7Kl8PakYkyadecqVuaHtMnc0DA2CQ=; b=cj/IaZFgVpTxuF8tcP2ORe8hP6 AzpBaJkU8th1JLvYB3XT080JjDgdbuQjBtdbVvNJUySVHFlSl5o8wPMcbsjRButyYpRDYcF+dfOLT IQnRiA8+xmsdG07M+4GqRUhePBgz/9O2MBdeFVs2SdsM0J6UzxxYtwQJq5UcpuENCvA02GCMIEirW KO0+LlfD7skCflEzNmYg2WRHW2w1+h75nQ3qxnUbRDhv9UlS7FPWBb4IInV8hRi1o084EWD8iP/aw ktlCE+5rZQ0LHQwJ4C+Q9syt2UiNOVuZtkLkjN8JIOH6xSR1rKzC0u0+g2DlOHHquPAaI/X5akUgb ctRZOkCw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRlw-000DsB-4S; Thu, 09 Dec 2021 22:20:17 +0000 Received: from mail-yb1-xb49.google.com ([2607:f8b0:4864:20::b49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRhw-000CIV-Eb for linux-arm-kernel@lists.infradead.org; Thu, 09 Dec 2021 22:16:10 +0000 Received: by mail-yb1-xb49.google.com with SMTP id t184-20020a2546c1000000b006008b13c80bso13101895yba.1 for ; Thu, 09 Dec 2021 14:16:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=a1e01/uQIMruIVMxVHsJI+lKzq1arm+BxjGSeQVMHMA=; b=PqB8Y03IRHWlUaGuR+3mpNmM+NV36jEBvM5WalY9UQa7LJQ3Ha7mLeU0SrXzuGpgv7 3f1FJ7nyOU1HKi0FN2fKfIxI5t5swTAFYDfuuNdYZhQqduoKHQ1cYMi4OIcVm53c3vCy 7yT5rL4j/PWClDNNlKwcRZOM73uddO3lpdJphfRR21b42NwPq21ghJtd4I9iZuBlLngU qCZ6m7MdzEt3RAGpy7Ix+uOw5VaFfqKUEZwR8gWh/+ky7IT5ELKb9UeUJd9IKkCKn5xq NkDxW8QZ9WvEJwcrHkgaoPFQ7+5GNQoVTcHihopQaPQAfuvCjJ80sufoumyAG3oTmcrm rdug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=a1e01/uQIMruIVMxVHsJI+lKzq1arm+BxjGSeQVMHMA=; b=fcTXKA6trgE/oC0xfJeSYawZUCS41GIB06jXLbUKKw4X7GSLNhVSjTxUf3jeMRE/5f M2UQfg8YSo8YLTmSj7kBFbCYuRFWoD1VNV+Qtoc3ixNLm/TFZTADnFa4tQMF6WByr/LN bLIMZToKCDcQTBBDyOR5whfN7/3fOlZHYPKW+cRv9/m6z2drATPUaQyt42y0aJjcMIXi OkbBySFejBHUDeqGDKAZmkY5q1NtuSxQRz1sFHG2QT9hvYWT6i/dCMCakgLTEO9PsYNY rrqmUblgQNx0HsINjtxrhNVv9KWfhxHZi85+E4FlsP3sigb8pJnLQjs1HulM9BFxXUV6 Qf0A== X-Gm-Message-State: AOAM532C/nC8wR+mFzpeD4HLjOBpjY2LBfHE9o0mFeeKYtjTRnDqedL1 fs/Re0mFzU8vS0TZRWYDta2aKSw= X-Google-Smtp-Source: ABdhPJxc0LQEcS2GZ0xtTl0rfiaEYOwwtlAW2WphlbELpXxEcghi8DcFKiFyg+sJxtCD3pCjqLRkEqw= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:f233:e324:8aa0:f65c]) (user=pcc job=sendgmr) by 2002:a25:2e49:: with SMTP id b9mr10139518ybn.414.1639088166927; Thu, 09 Dec 2021 14:16:06 -0800 (PST) Date: Thu, 9 Dec 2021 14:15:43 -0800 In-Reply-To: <20211209221545.2333249-1-pcc@google.com> Message-Id: <20211209221545.2333249-7-pcc@google.com> Mime-Version: 1.0 References: <20211209221545.2333249-1-pcc@google.com> X-Mailer: git-send-email 2.34.1.173.g76aa8bc2d0-goog Subject: [PATCH v4 6/7] Documentation: document uaccess logging From: Peter Collingbourne To: Catalin Marinas , Will Deacon , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Thomas Gleixner , Andy Lutomirski , Kees Cook , Andrew Morton , Masahiro Yamada , Sami Tolvanen , YiFei Zhu , Mark Rutland , Frederic Weisbecker , Viresh Kumar , Andrey Konovalov , Peter Collingbourne , Gabriel Krisman Bertazi , Chris Hyser , Daniel Vetter , Chris Wilson , Arnd Bergmann , Dmitry Vyukov , Christian Brauner , "Eric W. Biederman" , Alexey Gladkov , Ran Xiaokai , David Hildenbrand , Xiaofeng Cao , Cyrill Gorcunov , Thomas Cedeno , Marco Elver , Alexander Potapenko Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Evgenii Stepanov X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211209_141608_570985_5D832564 X-CRM114-Status: GOOD ( 31.35 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add documentation for the uaccess logging feature. Link: https://linux-review.googlesource.com/id/Ia626c0ca91bc0a3d8067d7f28406aa40693b65a2 Signed-off-by: Peter Collingbourne --- v3: - document what happens if passing NULL to prctl - be explicit about meaning of addr and size Documentation/admin-guide/index.rst | 1 + Documentation/admin-guide/uaccess-logging.rst | 151 ++++++++++++++++++ 2 files changed, 152 insertions(+) create mode 100644 Documentation/admin-guide/uaccess-logging.rst diff --git a/Documentation/admin-guide/index.rst b/Documentation/admin-guide/index.rst index 1bedab498104..4f6ee447ab2f 100644 --- a/Documentation/admin-guide/index.rst +++ b/Documentation/admin-guide/index.rst @@ -54,6 +54,7 @@ ABI will be found here. :maxdepth: 1 sysfs-rules + uaccess-logging The rest of this manual consists of various unordered guides on how to configure specific aspects of kernel behavior to your liking. diff --git a/Documentation/admin-guide/uaccess-logging.rst b/Documentation/admin-guide/uaccess-logging.rst new file mode 100644 index 000000000000..24def38bbdf8 --- /dev/null +++ b/Documentation/admin-guide/uaccess-logging.rst @@ -0,0 +1,151 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=============== +Uaccess Logging +=============== + +Background +---------- + +Userspace tools such as sanitizers (ASan, MSan, HWASan) and tools +making use of the ARM Memory Tagging Extension (MTE) need to +monitor all memory accesses in a program so that they can detect +memory errors. Furthermore, fuzzing tools such as syzkaller need to +monitor all memory accesses so that they know which parts of memory +to fuzz. For accesses made purely in userspace, this is achieved +via compiler instrumentation, or for MTE, via direct hardware +support. However, accesses made by the kernel on behalf of the user +program via syscalls (i.e. uaccesses) are normally invisible to +these tools. + +Traditionally, the sanitizers have handled this by interposing the libc +syscall stubs with a wrapper that checks the memory based on what we +believe the uaccesses will be. However, this creates a maintenance +burden: each syscall must be annotated with its uaccesses in order +to be recognized by the sanitizer, and these annotations must be +continuously updated as the kernel changes. + +The kernel's uaccess logging feature provides userspace tools with +the address and size of each userspace access, thereby allowing these +tools to report memory errors involving these accesses without needing +annotations for every syscall. + +By relying on the kernel's actual uaccesses, rather than a +reimplementation of them, the userspace memory safety tools may +play a dual role of verifying the validity of kernel accesses. Even +a sanitizer whose syscall wrappers have complete knowledge of the +kernel's intended API may vary from the kernel's actual uaccesses due +to kernel bugs. A sanitizer with knowledge of the kernel's actual +uaccesses may produce more accurate error reports that reveal such +bugs. For example, a kernel that accesses more memory than expected +by the userspace program could indicate that either userspace or the +kernel has the wrong idea about which kernel functionality is being +requested -- either way, there is a bug. + +Interface +--------- + +The feature may be used via the following prctl: + +.. code-block:: c + + uint64_t addr = 0; /* Generally will be a TLS slot or equivalent */ + prctl(PR_SET_UACCESS_DESCRIPTOR_ADDR_ADDR, &addr, 0, 0, 0); + +Supplying a non-zero address as the second argument to ``prctl`` +will cause the kernel to read an address (referred to as the *uaccess +descriptor address*) from that address on each kernel entry. Specifying +an address of NULL as the second argument will restore the kernel's +default behavior, i.e. no uaccess descriptor address is read. + +When entering the kernel with a non-zero uaccess descriptor address +to handle a syscall, the kernel will read a data structure of type +``struct uaccess_descriptor`` from the uaccess descriptor address, +which is defined as follows: + +.. code-block:: c + + struct uaccess_descriptor { + uint64_t addr, size; + }; + +This data structure contains the address and size (in array elements) +of a *uaccess buffer*, which is an array of data structures of type +``struct uaccess_buffer_entry``. Before returning to userspace, the +kernel will log information about uaccesses to sequential entries +in the uaccess buffer. It will also store ``NULL`` to the uaccess +descriptor address, and store the address and size of the unused +portion of the uaccess buffer to the uaccess descriptor. + +The format of a uaccess buffer entry is defined as follows: + +.. code-block:: c + + struct uaccess_buffer_entry { + uint64_t addr, size, flags; + }; + +``addr`` and ``size`` contain the address and size of the user memory +access. On arm64, tag bits are preserved in the ``addr`` field. There +is currently one flag bit assignment for the ``flags`` field: + +.. code-block:: c + + #define UACCESS_BUFFER_FLAG_WRITE 1 + +This flag is set if the access was a write, or clear if it was a +read. The meaning of all other flag bits is reserved. + +When entering the kernel with a non-zero uaccess descriptor +address for a reason other than a syscall (for example, when +IPI'd due to an incoming asynchronous signal), any signals other +than ``SIGKILL`` and ``SIGSTOP`` are masked as if by calling +``sigprocmask(SIG_SETMASK, set, NULL)`` where ``set`` has been +initialized with ``sigfillset(set)``. This is to prevent incoming +signals from interfering with uaccess logging. + +Example +------- + +Here is an example of a code snippet that will enumerate the accesses +performed by a ``uname(2)`` syscall: + +.. code-block:: c + + struct uaccess_buffer_entry entries[64]; + struct uaccess_descriptor desc; + uint64_t desc_addr = 0; + prctl(PR_SET_UACCESS_DESCRIPTOR_ADDR_ADDR, &desc_addr, 0, 0, 0); + + desc.addr = (uint64_t)&entries; + desc.size = 64; + desc_addr = (uint64_t)&desc; + + struct utsname un; + uname(&un); + + struct uaccess_buffer_entry* entries_end = (struct uaccess_buffer_entry*)desc.addr; + for (struct uaccess_buffer_entry* entry = entries; entry != entries_end; ++entry) { + printf("%s at 0x%lx size 0x%lx\n", entry->flags & UACCESS_BUFFER_FLAG_WRITE ? "WRITE" : "READ", + (unsigned long)entry->addr, (unsigned long)entry->size); + } + +Limitations +----------- + +This feature is currently only supported on the arm64, s390 and x86 +architectures. + +Uaccess buffers are a "best-effort" mechanism for logging uaccesses. Of +course, not all of the accesses may fit in the buffer, but aside from +that, not all internal kernel APIs that access userspace memory are +covered. Therefore, userspace programs should tolerate unreported +accesses. + +On the other hand, the kernel guarantees that it will not +(intentionally) report accessing more data than it is specified +to read. For example, if the kernel implements a syscall that is +specified to read a data structure of size ``N`` bytes by first +reading a page's worth of data and then only using the first ``N`` +bytes from it, the kernel will either report reading ``N`` bytes or +not report the access at all. From patchwork Thu Dec 9 22:15:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12695544 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 2BAF6C433EF for ; Thu, 9 Dec 2021 22:24:05 +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:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=I7tL2g9zjJ7dH81X3nK14dBc0ikgrRs4g1GqpbQOH/s=; b=Dpn/1FskfU3wm2ShroLLE9ayO9 574jKLnYaK3YNYDxUWHpiYBFdYc2ZCFoXChZ+gyAZbuoBMQKL4Ra1dhgbUHyUaD6Ef7RRorD4MTSk ZxhYjQnMqYNlfZqomdOzf+OsVD/UtOYpXdeyiLDr/KtfqxACnNhynRK/W/er5WLDYE9orWNPUVMN2 JGfSQicPfAgKioyLhRQr1j84qyv25V8u4szVz/p8clajaiZ70NrtrQ10qOdvbt3e0x/s65/eEqAI8 bhi6kte97uPLzMuRYidTsaux2UMo4ACFK1KaHbfuQRIZFpEwTq9LkuxLGkbkFXP+e8Lx2kIGe1qXj cH6oxNVg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRmz-000EGn-OW; Thu, 09 Dec 2021 22:21:21 +0000 Received: from mail-yb1-xb4a.google.com ([2607:f8b0:4864:20::b4a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mvRhz-000CJz-G4 for linux-arm-kernel@lists.infradead.org; Thu, 09 Dec 2021 22:16:13 +0000 Received: by mail-yb1-xb4a.google.com with SMTP id l145-20020a25cc97000000b005c5d04a1d52so12960645ybf.23 for ; Thu, 09 Dec 2021 14:16:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=7s8lEM7vxE9oaPCZlcOUwoJ7eBiwu3eQIZufuhM0E/I=; b=ksiw6rsrwZIql9RdnW0zggcto4PhW/OFyE3GwNIVspYOeSFVcU4OkzOgvF2gkZxccX bAnBjk2/2N5TBjb6PPhpPTI5e3DYoUJD5tZwq0N5PSC/VkLZazfhOdl6845mojjGoYbF Buzlq6livqIu8JOBvfszFn7XyWPq/2p4YBpY951LGKJItM1FxAOT1mmHT1j27pWh888j dld8HWIzS5VL+QI7m+LZ0U0gM8P7ddbKo4Pvn11v8jO49iN2xZKt8n8dIF/5j87eios1 QnYYtIRfkgsBGqFgPTs8F95xXML5xU2T5M8ABRFTtl9jAyzWCGpszQkfWUK+FFOLIxSC MMcg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=7s8lEM7vxE9oaPCZlcOUwoJ7eBiwu3eQIZufuhM0E/I=; b=b6HCmPoqxGu+V7CLIhZxn1BMmKA+UFLoGT1+R8TpS5C5zbreji9cqKutQDA7qEu9ut scFWBf2xpbiyhqLcQlUD/BuGUh9PryjHpbxdc54bYt+b7F9S4pN3iK9GntuTb5Zwi/O2 lL70l+tVM+haNVxbYNgD/8kGF0ejC414+ALh6l9mpMYK5RUmJII1jyaaT3bZGGMWM3+Z bjs6q3lVIBPUNuQOMhJ7b39RyLOs4og476Lye9Ql/O3NoY245Llav8cWtR9MaluNKf2o RsSUa2TwJ6hE4e1Mw2FeDdb4hh+5ObW9yI4anV1g+jxFkD2cWuw/0Ez87maEUUg1Wbwc 9fGw== X-Gm-Message-State: AOAM5309W2xNdmejUUYXJQdgi3D2ux/d6Bef9DoZ3uYrpWGCQvEuBJJd fjteU68JbuHNouw8qCE1UKWkiSk= X-Google-Smtp-Source: ABdhPJx6SHlSTXft/4uwAkd2t2Qz2vUlOSahwEB+bAnZk0choINS/4CYmxqXe6LtfY7i28pAboGp1Qc= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:f233:e324:8aa0:f65c]) (user=pcc job=sendgmr) by 2002:a05:6902:1107:: with SMTP id o7mr9802261ybu.120.1639088169471; Thu, 09 Dec 2021 14:16:09 -0800 (PST) Date: Thu, 9 Dec 2021 14:15:44 -0800 In-Reply-To: <20211209221545.2333249-1-pcc@google.com> Message-Id: <20211209221545.2333249-8-pcc@google.com> Mime-Version: 1.0 References: <20211209221545.2333249-1-pcc@google.com> X-Mailer: git-send-email 2.34.1.173.g76aa8bc2d0-goog Subject: [PATCH v4 7/7] selftests: test uaccess logging From: Peter Collingbourne To: Catalin Marinas , Will Deacon , Ingo Molnar , Peter Zijlstra , Juri Lelli , Vincent Guittot , Dietmar Eggemann , Steven Rostedt , Ben Segall , Mel Gorman , Daniel Bristot de Oliveira , Thomas Gleixner , Andy Lutomirski , Kees Cook , Andrew Morton , Masahiro Yamada , Sami Tolvanen , YiFei Zhu , Mark Rutland , Frederic Weisbecker , Viresh Kumar , Andrey Konovalov , Peter Collingbourne , Gabriel Krisman Bertazi , Chris Hyser , Daniel Vetter , Chris Wilson , Arnd Bergmann , Dmitry Vyukov , Christian Brauner , "Eric W. Biederman" , Alexey Gladkov , Ran Xiaokai , David Hildenbrand , Xiaofeng Cao , Cyrill Gorcunov , Thomas Cedeno , Marco Elver , Alexander Potapenko Cc: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Evgenii Stepanov X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211209_141611_608445_0C17EA67 X-CRM114-Status: GOOD ( 24.67 ) X-BeenThere: linux-arm-kernel@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-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a kselftest for the uaccess logging feature. Link: https://linux-review.googlesource.com/id/I39e1707fb8aef53747c42bd55b46ecaa67205199 Signed-off-by: Peter Collingbourne --- tools/testing/selftests/Makefile | 1 + .../testing/selftests/uaccess_buffer/Makefile | 4 + .../uaccess_buffer/uaccess_buffer_test.c | 126 ++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 tools/testing/selftests/uaccess_buffer/Makefile create mode 100644 tools/testing/selftests/uaccess_buffer/uaccess_buffer_test.c diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index c852eb40c4f7..291b62430557 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -71,6 +71,7 @@ TARGETS += timers endif TARGETS += tmpfs TARGETS += tpm2 +TARGETS += uaccess_buffer TARGETS += user TARGETS += vDSO TARGETS += vm diff --git a/tools/testing/selftests/uaccess_buffer/Makefile b/tools/testing/selftests/uaccess_buffer/Makefile new file mode 100644 index 000000000000..e6e5fb43ce29 --- /dev/null +++ b/tools/testing/selftests/uaccess_buffer/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 +TEST_GEN_PROGS := uaccess_buffer_test + +include ../lib.mk diff --git a/tools/testing/selftests/uaccess_buffer/uaccess_buffer_test.c b/tools/testing/selftests/uaccess_buffer/uaccess_buffer_test.c new file mode 100644 index 000000000000..051062e4fbf9 --- /dev/null +++ b/tools/testing/selftests/uaccess_buffer/uaccess_buffer_test.c @@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include "../kselftest_harness.h" + +#include +#include +#include + +FIXTURE(uaccess_buffer) +{ + uint64_t addr; +}; + +FIXTURE_SETUP(uaccess_buffer) +{ + ASSERT_EQ(0, prctl(PR_SET_UACCESS_DESCRIPTOR_ADDR_ADDR, &self->addr, 0, + 0, 0)); +} + +FIXTURE_TEARDOWN(uaccess_buffer) +{ + ASSERT_EQ(0, prctl(PR_SET_UACCESS_DESCRIPTOR_ADDR_ADDR, 0, 0, 0, 0)); +} + +TEST_F(uaccess_buffer, uname) +{ + struct uaccess_descriptor desc; + struct uaccess_buffer_entry entries[64]; + struct utsname un; + + desc.addr = (uint64_t)(unsigned long)entries; + desc.size = 64; + self->addr = (uint64_t)(unsigned long)&desc; + ASSERT_EQ(0, uname(&un)); + ASSERT_EQ(0, self->addr); + + if (desc.size == 63) { + ASSERT_EQ((uint64_t)(unsigned long)(entries + 1), desc.addr); + + ASSERT_EQ((uint64_t)(unsigned long)&un, entries[0].addr); + ASSERT_EQ(sizeof(struct utsname), entries[0].size); + ASSERT_EQ(UACCESS_BUFFER_FLAG_WRITE, entries[0].flags); + } else { + /* See override_architecture in kernel/sys.c */ + ASSERT_EQ(62, desc.size); + ASSERT_EQ((uint64_t)(unsigned long)(entries + 2), desc.addr); + + ASSERT_EQ((uint64_t)(unsigned long)&un, entries[0].addr); + ASSERT_EQ(sizeof(struct utsname), entries[0].size); + ASSERT_EQ(UACCESS_BUFFER_FLAG_WRITE, entries[0].flags); + + ASSERT_EQ((uint64_t)(unsigned long)&un.machine, + entries[1].addr); + ASSERT_EQ(UACCESS_BUFFER_FLAG_WRITE, entries[1].flags); + } +} + +static bool handled; + +static void usr1_handler(int signo) +{ + handled = true; +} + +TEST_F(uaccess_buffer, blocked_signals) +{ + struct uaccess_descriptor desc; + struct shared_buf { + bool ready; + bool killed; + } volatile *shared = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0); + struct sigaction act = {}, oldact; + int pid; + + handled = false; + act.sa_handler = usr1_handler; + sigaction(SIGUSR1, &act, &oldact); + + pid = fork(); + if (pid == 0) { + /* + * Busy loop to synchronize instead of issuing syscalls because + * we need to test the behavior in the case where no syscall is + * issued by the parent process. + */ + while (!shared->ready) + ; + kill(getppid(), SIGUSR1); + shared->killed = true; + _exit(0); + } else { + int i; + + desc.addr = 0; + desc.size = 0; + self->addr = (uint64_t)(unsigned long)&desc; + + shared->ready = true; + while (!shared->killed) + ; + + /* + * The kernel should have IPI'd us by now, but let's wait a bit + * longer just in case. + */ + for (i = 0; i != 1000000; ++i) + ; + + ASSERT_FALSE(handled); + + /* + * Returning from the waitpid syscall should trigger the signal + * handler. The signal itself may also interrupt waitpid, so + * make sure to handle EINTR. + */ + while (waitpid(pid, NULL, 0) == -1) + ASSERT_EQ(EINTR, errno); + ASSERT_TRUE(handled); + } + + munmap((void *)shared, getpagesize()); + sigaction(SIGUSR1, &oldact, NULL); +} + +TEST_HARNESS_MAIN