From patchwork Tue Nov 23 05:16:54 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12693404 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 154E3C433F5 for ; Tue, 23 Nov 2021 05:18:57 +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=1sEo4cwITZ7Xp/wUj0qP66yzTiO2zW+C/Zf6Zw4SYkA=; b=q+kTtd0KqByoLNoLiyYLx/LcJI nanoaeAlLf17+bZPWZx+Je+TnHOG7g5PDhgnnzG6e3cJTBKhaiyvY6ZiK/hH/qe8h2pDKChyZ4yNq pf8sLUEeIqwaRNmMKrUnwCTs25+jLpYbHV5DV/ZNvJlEAdYx+u8phQ6eyK3zI34uUvxFQ1x9D9/uj q7lX5g0Uzpa2GyxcfMIREmIwaBBSLc+g81sdaVUxsdEmsaTfSHohvma3QnVX0DMuep9tQRB+BcMOG WfPUuEqC4P5E0Vm7bynnr6EMTAJTQ/y0JrQ+Ho2BGGsJGSZe9B5W5EiuxBNowCEFCEZ1aN27xtiG/ /FBXc5BQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpOBM-000psG-IW; Tue, 23 Nov 2021 05:17:28 +0000 Received: from mail-pf1-x44a.google.com ([2607:f8b0:4864:20::44a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpOB6-000pkS-OP for linux-arm-kernel@lists.infradead.org; Tue, 23 Nov 2021 05:17:14 +0000 Received: by mail-pf1-x44a.google.com with SMTP id x14-20020a627c0e000000b0049473df362dso11101785pfc.12 for ; Mon, 22 Nov 2021 21:17:08 -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=NFXAGR/xc49oqhNC41J0AQLDYJfxO7+Jxraub53Emyc=; b=ey7cdPuXo53FwDLmzr6OCkG/WgkXsyr7tpMu5mUd6CjU6Aiu5BGVyYKwf7ZRGqKNkW XCJvfuxbdEtqOUBqhjgOJkeGLjrf0FWukN82g40hpufMkzHuIrh/LLe/cILZp2xvU/mQ +oZZ0IzOAPAnSQVm6xLuBThCj3bV7b9Zt9T1Ldv9PpZUW15NXdxa4hMIKKEjMXqbNGxQ lpE+m1hXxc8ppyMpxBughfEowTTd2+zEdQnJAO+07UCh1VU52n2qC2xY4DQioiMtX6GX WJSeeIvpchw+UeeV8z87iFesRr5KFS+mO+4c6V6WVidi0rxrBjBucNuBqEv+8l7+yBb9 iJ5Q== 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=NFXAGR/xc49oqhNC41J0AQLDYJfxO7+Jxraub53Emyc=; b=RmBc+O/k+nh91DzNSpB0dsPgmYbTuaJPuqYBoHJlFXZ6XjZkggsMgqNRGpVUGrWfI7 DxWDrcggc9RwRIl3XxCZfhph4Q4ewE9x06f/zZAExX3ospErC6ur2ADC5IihQQJ3s+A6 eilB48xUGO3/FKBS9qM/JZPIAsTotL0HDbVZOuALEZMrlaxcepiipO7NcwEvGRbCvlBD 7RXEgMKjHb5mZXPT217wXJv+KDf5ae06BRpg9OEKA9LeVUFrEvRRSpEefugCOUsFrzQr dOdN6w8LKVLlNDAqnIg0hObgQoI607XR2v+UE5gFYIrlP44UtlxDxPN0L2dHG64ESv4h HGmg== X-Gm-Message-State: AOAM530AEVH9XlcMFIIt5byE1fE6MpBNGF5MG54y7qml1PR72H0x10tb VavJThVq6QwOjeAUWPmiyaenJVQ= X-Google-Smtp-Source: ABdhPJzxQakGABdjIJCQjLa7F4VRbS3dyTefpbTS5bC19PmFmcSwZH41uUXPqwC9QBE4HVmcOu0sevE= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:a876:2e6a:b5f:3d90]) (user=pcc job=sendgmr) by 2002:a63:1d13:: with SMTP id d19mr1879264pgd.383.1637644628236; Mon, 22 Nov 2021 21:17:08 -0800 (PST) Date: Mon, 22 Nov 2021 21:16:54 -0800 In-Reply-To: <20211123051658.3195589-1-pcc@google.com> Message-Id: <20211123051658.3195589-2-pcc@google.com> Mime-Version: 1.0 References: <20211123051658.3195589-1-pcc@google.com> X-Mailer: git-send-email 2.34.0.rc2.393.gf8c9666880-goog Subject: [PATCH v2 1/5] fs: use raw_copy_from_user() 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 , Colin Ian King , 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-20211122_211712_821284_4AFBEE31 X-CRM114-Status: GOOD ( 18.30 ) 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 raw_copy_from_user(), 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 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/namespace.c b/fs/namespace.c index 659a8f39c61a..695b30e391f0 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -3197,7 +3197,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 raw_copy_from_user to avoid reporting overly large accesses in + * the uaccess buffer, as this can lead to false positive reports in + * downstream consumers. + */ + left = raw_copy_from_user(copy, data, PAGE_SIZE); /* * Not all architectures have an exact copy_from_user(). Resort to From patchwork Tue Nov 23 05:16:55 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12693406 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 CD881C433F5 for ; Tue, 23 Nov 2021 05:19:33 +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=Ys7vQ+VC5qqxBMUh/e9ExFWdr7PEfQDqcBx01i7r1rI=; b=HEMmUQ6Pm2sfJ9cBawX3Jz8Heh I/ZEDV3SCS2y314lWXnuJyVPVhzZleVqigM8UovXzYuwVCsK9hSX3frx26b9rrSwe4f8RE1W10H3v nY42oPZylJplHtPyoMe36rhKPjKikHZVuER23FlEsXmSgcyKOLspWnd2NHLcE5Vtdh1zb2LTtO4HS 9mkirIesNMFWcZY4unUfJc1i0PnIcZjg4YVnA2GJRZr0zubBgLlxNMCQSIgN4vsGsbMj/Zp91vKJR Bl7oGx0rmWpYeOu0sglcxga0ShDyX7BMmjZxnTjsnaUiW3+O4U+ayNGBffFe1F0X7ueYJrj70Z6Hu I6CKOXBA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpOBq-000q0m-0h; Tue, 23 Nov 2021 05:17:58 +0000 Received: from mail-pl1-x64a.google.com ([2607:f8b0:4864:20::64a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpOB7-000pks-Vn for linux-arm-kernel@lists.infradead.org; Tue, 23 Nov 2021 05:17:18 +0000 Received: by mail-pl1-x64a.google.com with SMTP id p3-20020a170903248300b00143c00a5411so8549142plw.12 for ; Mon, 22 Nov 2021 21:17: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=TQIf/OIUVwGkxbYI32rejLRLSDrVm5MLPR+mboxvR5U=; b=IyYqQYg4PxGSfKhIUCW7Qqb/DNY9bL7t85jnFiptJc/PIfBvsajpLCYGW/v6AGJDQH QerrpOLxdhCfzAG7MreMDfB/QIjytpjf4wAjAk49eGwGmH4Jte3FKnbu3x8DIv2kEKvc DtPARbNm04SIS3LvipxKb5tJCgGozzXoLrNfkUp1l8PPlj+CtnS2Xi5vnE6TxQs9xkCO xU7PEtR7PBCvc7tR9NTUiscw0Mzty6cNlHB/gVrW8QVu0X+ERlC15WHbYTClfbL1csmE bUUKMvA7WLt8hbX6SQGFL+w4sxjGpmCjMsgsWRZUTDS7E/fy+ptRbfBWxxurL/NDjSql HqXg== 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=TQIf/OIUVwGkxbYI32rejLRLSDrVm5MLPR+mboxvR5U=; b=ltiKmjL0uJIIV41EDPyUDEQuuQJQYHZD8Qr6gb7Os0zN2M0YS3/oAVq0duWZRbCE9x 7wCB5mB3WAb4u9Zg/4rULno6USTCUuBLy1EHqCvKWNl+5k5fBpyce6mi/xeeGYO1QVzz blM8qiyC0kTuGFi3epwLP1ZFdvqxjUCXRbOX61550zY5auaxCEpEHL2cQNApISW2AIv5 yorr25HlEkI208OUqgQSaviwU01TbEP2jOsdsUWElK8yWl4mWOApr267UfTrP3kHMRdE cHD5px6BOCRpCsyNohdsJWp2X4dQt+pQIMhRbnhLuYkNRjbjI6s7FtiJR2xGKTrCBuIP g+cA== X-Gm-Message-State: AOAM531oUFJ+JaAXG5+tF2hyVxJHJhIaTDp3gjlVJKSJRV7ck2FGAgky 2jgEql64Ll/Ui+FeaqhGiLeF42s= X-Google-Smtp-Source: ABdhPJwlLZKO/n9a2aoJ8uvvHMB0+nvlxyQ3QG3hLOgWLW5DUO4ylwv7GNhUmxqFZnNLsSzYO7Z4E5I= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:a876:2e6a:b5f:3d90]) (user=pcc job=sendgmr) by 2002:a05:6a00:2181:b0:44c:f4bc:2f74 with SMTP id h1-20020a056a00218100b0044cf4bc2f74mr2505169pfi.68.1637644630354; Mon, 22 Nov 2021 21:17:10 -0800 (PST) Date: Mon, 22 Nov 2021 21:16:55 -0800 In-Reply-To: <20211123051658.3195589-1-pcc@google.com> Message-Id: <20211123051658.3195589-3-pcc@google.com> Mime-Version: 1.0 References: <20211123051658.3195589-1-pcc@google.com> X-Mailer: git-send-email 2.34.0.rc2.393.gf8c9666880-goog Subject: [PATCH v2 2/5] 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 , Colin Ian King , 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-20211122_211714_105939_92154553 X-CRM114-Status: GOOD ( 33.69 ) 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 --- 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 | 5 + fs/exec.c | 2 + include/linux/instrumented.h | 5 +- include/linux/sched.h | 4 + include/linux/uaccess-buffer-log-hooks.h | 59 +++++++++++ include/linux/uaccess-buffer.h | 79 ++++++++++++++ include/uapi/linux/prctl.h | 3 + include/uapi/linux/uaccess-buffer.h | 25 +++++ kernel/Makefile | 1 + kernel/bpf/helpers.c | 6 +- kernel/fork.c | 3 + kernel/signal.c | 4 +- kernel/sys.c | 6 ++ kernel/uaccess-buffer.c | 125 +++++++++++++++++++++++ 14 files changed, 324 insertions(+), 3 deletions(-) create mode 100644 include/linux/uaccess-buffer-log-hooks.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 26b8ed11639d..6030298a7e9a 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -1302,6 +1302,11 @@ 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. + source "kernel/gcov/Kconfig" source "scripts/gcc-plugins/Kconfig" diff --git a/fs/exec.c b/fs/exec.c index 537d92c41105..5f30314f3ec6 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -65,6 +65,7 @@ #include #include #include +#include #include #include @@ -1313,6 +1314,7 @@ 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); /* * We have to apply CLOEXEC before we change whether the process is diff --git a/include/linux/instrumented.h b/include/linux/instrumented.h index 42faebbaa202..c96be1695614 100644 --- a/include/linux/instrumented.h +++ b/include/linux/instrumented.h @@ -2,7 +2,7 @@ /* * This header provides generic wrappers for memory access instrumentation that - * the compiler cannot emit for: KASAN, KCSAN. + * the compiler cannot emit for: KASAN, KCSAN, uaccess buffers. */ #ifndef _LINUX_INSTRUMENTED_H #define _LINUX_INSTRUMENTED_H @@ -11,6 +11,7 @@ #include #include #include +#include /** * instrument_read - instrument regular read access @@ -117,6 +118,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); } /** @@ -134,6 +136,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_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 78c351e35fec..1f978deaa3f8 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1484,6 +1484,10 @@ struct task_struct { struct callback_head l1d_flush_kill; #endif +#ifdef CONFIG_HAVE_ARCH_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-log-hooks.h b/include/linux/uaccess-buffer-log-hooks.h new file mode 100644 index 000000000000..bddc84ddce32 --- /dev/null +++ b/include/linux/uaccess-buffer-log-hooks.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_UACCESS_BUFFER_LOG_HOOKS_H +#define _LINUX_UACCESS_BUFFER_LOG_HOOKS_H + +#ifdef CONFIG_HAVE_ARCH_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. + */ + 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; +}; + +void uaccess_buffer_log_read(const void __user *from, unsigned long n); +void uaccess_buffer_log_write(void __user *to, unsigned long n); + +#else + +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_LOG_HOOKS_H */ diff --git a/include/linux/uaccess-buffer.h b/include/linux/uaccess-buffer.h new file mode 100644 index 000000000000..14261368d3a9 --- /dev/null +++ b/include/linux/uaccess-buffer.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_UACCESS_BUFFER_H +#define _LINUX_UACCESS_BUFFER_H + +#include +#include + +#include + +#ifdef CONFIG_HAVE_ARCH_UACCESS_BUFFER + +static inline bool uaccess_buffer_maybe_blocked(struct task_struct *tsk) +{ + return tsk->uaccess_buffer.desc_ptr_ptr; +} + +void __uaccess_buffer_syscall_entry(void); +static inline void uaccess_buffer_syscall_entry(void) +{ + if (uaccess_buffer_maybe_blocked(current)) + __uaccess_buffer_syscall_entry(); +} + +void __uaccess_buffer_syscall_exit(void); +static inline void uaccess_buffer_syscall_exit(void) +{ + if (uaccess_buffer_maybe_blocked(current)) + __uaccess_buffer_syscall_exit(); +} + +bool __uaccess_buffer_pre_exit_loop(void); +static inline bool uaccess_buffer_pre_exit_loop(void) +{ + if (!uaccess_buffer_maybe_blocked(current)) + return false; + return __uaccess_buffer_pre_exit_loop(); +} + +void __uaccess_buffer_post_exit_loop(void); +static inline void uaccess_buffer_post_exit_loop(bool pending) +{ + if (pending) + __uaccess_buffer_post_exit_loop(); +} + +void uaccess_buffer_cancel_log(struct task_struct *tsk); +int uaccess_buffer_set_descriptor_addr_addr(unsigned long addr); + +#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 void uaccess_buffer_cancel_log(struct task_struct *tsk) +{ +} + +static inline int uaccess_buffer_set_descriptor_addr_addr(unsigned long addr) +{ + return -EINVAL; +} +#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..619b17dc25c4 --- /dev/null +++ b/include/uapi/linux/uaccess-buffer.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_UACCESS_BUFFER_H +#define _UAPI_LINUX_UACCESS_BUFFER_H + +/* 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..d4d9be5146c3 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_HAVE_ARCH_UACCESS_BUFFER) += uaccess-buffer.o obj-$(CONFIG_PERF_EVENTS) += events/ diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c index 649f07623df6..167b50177066 100644 --- a/kernel/bpf/helpers.c +++ b/kernel/bpf/helpers.c @@ -637,7 +637,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 copy_from_user() here as it may leak information about the BPF + * program to userspace via the uaccess buffer. + */ + int ret = raw_copy_from_user(dst, user_ptr, size); if (unlikely(ret)) { memset(dst, 0, size); diff --git a/kernel/fork.c b/kernel/fork.c index 3244cc56b697..c7abe7e7c7cd 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -96,6 +96,7 @@ #include #include #include +#include #include #include @@ -890,6 +891,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_cancel_log(tsk); + 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..69bf21518bd0 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. */ 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..e1c6d6ab9af8 --- /dev/null +++ b/kernel/uaccess-buffer.c @@ -0,0 +1,125 @@ +// 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 + +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 || unlikely(uaccess_kernel())) + return; + entry->addr = addr; + entry->size = size; + entry->flags = flags; + + ++buf->kcur; + if (buf->kcur == buf->kend) + buf->kcur = 0; +} + +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); + +int uaccess_buffer_set_descriptor_addr_addr(unsigned long addr) +{ + current->uaccess_buffer.desc_ptr_ptr = + (struct uaccess_descriptor __user * __user *)addr; + uaccess_buffer_cancel_log(current); + return 0; +} + +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) +{ + spin_lock_irq(¤t->sighand->siglock); + current->blocked = current->real_blocked; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); +} + +void uaccess_buffer_cancel_log(struct task_struct *tsk) +{ + struct uaccess_buffer_info *buf = &tsk->uaccess_buffer; + + if (buf->kcur) { + buf->kcur = 0; + kfree(buf->kbegin); + } +} + +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; + + buf->kbegin = kmalloc_array( + desc.size, sizeof(struct uaccess_buffer_entry), GFP_KERNEL); + buf->kcur = buf->kbegin; + buf->kend = buf->kbegin + desc.size; + buf->ubegin = (struct uaccess_buffer_entry __user *)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; + + if (!buf->kcur) + return; + + desc.addr = (u64)(buf->ubegin + num_entries); + desc.size = buf->kend - buf->kcur; + buf->kcur = 0; + 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)); + + kfree(buf->kbegin); +} From patchwork Tue Nov 23 05:16:56 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12693405 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 1A7F6C433EF for ; Tue, 23 Nov 2021 05:19:16 +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=oa53bgLpniboKGGQIZhyVNRJh1hxse8GHUokxypubTM=; b=Iwo0qsMeK1Y1wLOoQvsJuNhgpW y3FMnO3ojMbkkW7VXlNRC5qpzuX2hNLoM+37pMFuFXOnxBbN93Zq6OK1dcwgmegj/teom2SHWyC1A Bbc9yFf1mo7oabiK6X7eZznpSUyEjU46/T4tYzrrM/u2vTqPjVgi2qcBWoLgKyZeDQugqb8eMA8Hj FmK4aDAWLO4Na323uHpn1m3OPodKO/RdXJHmItfJDISF8m/nAvUPnKBXKJ9ZuV0H3dbsHFWPsuYKh BKUMKzuMOMXhha71XeWNfUu5jeM7dmy9vgaLzTYpB5ewvWhTE5ncwp3uSZescLYNtPTJLjRDuef9G TRBqw2wA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpOBZ-000pvh-1R; Tue, 23 Nov 2021 05:17:41 +0000 Received: from mail-pg1-x549.google.com ([2607:f8b0:4864:20::549]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpOB8-000ple-H9 for linux-arm-kernel@lists.infradead.org; Tue, 23 Nov 2021 05:17:16 +0000 Received: by mail-pg1-x549.google.com with SMTP id i25-20020a631319000000b002cce0a43e94so7300103pgl.0 for ; Mon, 22 Nov 2021 21:17:13 -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=8YikxNtJWprMq/CBpWme0BytzCpItwTnBs0JI4g7h9M=; b=lr6jU+zyqsyUdEReZStYl3G49ZtLUI4FRjCCI6LwgfA4iWEF/hAOiHguW2mLPV1Jtb biEpdOkX+tP/eucrb3hTSTUeEZAA8IsY+FefkgpQdDEGEyBdG88kn1vOx1Hd751cdqgq RLanQtSikpeJXqg6AAuW28D/m0PfuXZK4I3yzqPhN9RlTWTcekgjkOvF6Vsxi5lwEeNy 4wfRl9Z9bjQSpxQaX89JGaOgKUnGpJjW2R81rbPp9qxmxlZ8OBNbEJVP3Maxvx6n4LeI PP+461MV/ampBKAJSBy4cJER48/666Tg+Hr3u6I8bSlmmHSp8KueiAApUUGR5RSamMw5 uFUA== 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=8YikxNtJWprMq/CBpWme0BytzCpItwTnBs0JI4g7h9M=; b=Wb5g//eVQsBBmvrJ9g76oogUYg0o693kAU/rcPgtU5zqlyNmcPgnVnywM8TgJeVqit ZQpldkPk+FLMC+iJjoEA+nDRXb2q8cehuMu7HyysqlB96o8MBDoxOTNGTYJ3+lOr8IH4 uTGxR4Lwkq2qp6dQ4atJnw+RYFhmSW381ibZE21J72poiAUEXsMNvew3DKy+H2/YX9v9 Qk/YooLV8DnHsifB+PpmHepW4Dbrz6hLAE9J5LasddYLMXVxHbsOT1TTGP6w+QiFWFYe jiE9p3S0k5FykiJL0KbWRqslvg0A404BTugKUX76qBuvsBpNOjED0ugzlniAB7TMSYKW eurg== X-Gm-Message-State: AOAM53216TlCKOvqp2qSJFGzquz5E/SGVhMScu5cdiPRHcY4UPhKlb7/ ikZxuWxKKcdKW8JFe/AvRPy70+E= X-Google-Smtp-Source: ABdhPJwFUF+MOVa4cKF7Nt3P3AYhZy5krLbbXlzRU0jE0MJn5GpfDjdnS4lCLzffhUcQ+vx5zPvE5Jk= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:a876:2e6a:b5f:3d90]) (user=pcc job=sendgmr) by 2002:a17:90a:a396:: with SMTP id x22mr3308358pjp.14.1637644632438; Mon, 22 Nov 2021 21:17:12 -0800 (PST) Date: Mon, 22 Nov 2021 21:16:56 -0800 In-Reply-To: <20211123051658.3195589-1-pcc@google.com> Message-Id: <20211123051658.3195589-4-pcc@google.com> Mime-Version: 1.0 References: <20211123051658.3195589-1-pcc@google.com> X-Mailer: git-send-email 2.34.0.rc2.393.gf8c9666880-goog Subject: [PATCH v2 3/5] 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 , Colin Ian King , 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-20211122_211714_600356_193AB1FB X-CRM114-Status: GOOD ( 15.02 ) 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 --- arch/Kconfig | 1 + kernel/entry/common.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/arch/Kconfig b/arch/Kconfig index 6030298a7e9a..bc9cdbfdb57e 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/kernel/entry/common.c b/kernel/entry/common.c index d5a61d565ad5..e06f88f77a70 100644 --- a/kernel/entry/common.c +++ b/kernel/entry/common.c @@ -6,6 +6,7 @@ #include #include #include +#include #include "common.h" @@ -89,6 +90,8 @@ __syscall_enter_from_user_work(struct pt_regs *regs, long syscall) if (work & SYSCALL_WORK_ENTER) syscall = syscall_trace_enter(regs, syscall, work); + uaccess_buffer_syscall_entry(); + return syscall; } @@ -197,14 +200,17 @@ 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(); + uaccess_buffer_pending = uaccess_buffer_pre_exit_loop(); if (unlikely(ti_work & EXIT_TO_USER_MODE_WORK)) 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); @@ -271,6 +277,7 @@ static void syscall_exit_to_user_mode_prepare(struct pt_regs *regs) local_irq_enable(); } + uaccess_buffer_syscall_exit(); rseq_syscall(regs); /* From patchwork Tue Nov 23 05:16:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12693407 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 DA585C433F5 for ; Tue, 23 Nov 2021 05:19:51 +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=55Gkn9kt5oyUCvLPMd/kaJyRdWqR40emsK8d5aN0DWs=; b=Wx1/MdfKL36UIOAdVhw7QqXQFT JxXHYZFPnTgKUiob1HYzf2q7CfNc4+uC0rGW9Vy8Upv7MzctCtAwzaZ4nleitYipb7hxPZY4rZTG4 sEBKzJV7QexxDTuYHlosrfe4k//sKLvkze67VWsdxRz5xCuGOcNza2EdFQVHMjJvVuh8dtbS9IhTu Xb7jJpd1mJIEJ/jVYSjxyKwYi4+KiwNTq2e8QzDqKSqcdQoGaJUz7NXD+ZznjxOvKWb1JMJ3YHXfd GeHRgG6ZXQfmnKyEbh21TFVQyOOo7L9EI/cNyV/lk8K3u6KtIZvRH8sUD/M7dwTWC0IhgXpN5NVVb nwUzcikA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpOC8-000q6b-Ew; Tue, 23 Nov 2021 05:18:16 +0000 Received: from mail-pl1-x64a.google.com ([2607:f8b0:4864:20::64a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpOB9-000pmx-Og for linux-arm-kernel@lists.infradead.org; Tue, 23 Nov 2021 05:17:19 +0000 Received: by mail-pl1-x64a.google.com with SMTP id m15-20020a170902bb8f00b0014382b67873so8523445pls.19 for ; Mon, 22 Nov 2021 21:17:15 -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=Gty7Zd/Q5CRamg0gViS3X7VJ+4Eadmw90vku2OpMNR0=; b=i/FXNGYOe6PsaAxbsnm5RGEXWjnL3mlA0e019XvhMTOJ5jD4eah5o10OrcCelr/+Kl ZCM2ArN5xFg4uUGA14TEzzB9T6xMiVV8vnTqfAgIA8oDmPxZX9uO0g4m7cJz9wDoE60I 8PaUFXRlW0g5PbblIX6ZjKKdA3R5nPolWGTC0LJY/1HADB+JZ2PXA/qgv2/Vd6DLk0x1 ACkLigqPuw73RSKSoes5ibDH1aSgWsx5znBsEbKJQ9O9Du1eZTpBTNjVVNtCXH1cLSxM UUhv9tSV/ymEW9G/ux+VJtX/iMdy7Ce7KVAUyVi8CHOlReV4hJ1wZRr6H01xEcm3nU4K I2CQ== 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=Gty7Zd/Q5CRamg0gViS3X7VJ+4Eadmw90vku2OpMNR0=; b=YMhZtLSpxlAtJGNoUM4pIo/2b1VveXq6YcrptBaX+tZRt9uOyzDnkwP4aaG3kmCBhE c8X0rWlf/RF6lleS0rXltamBPO8ClPuDvKlSivArwmIZjm8hKRiLdulkkpAuA3/Ctd8x NxuIX74DtwkYkmMKKY9tSD2wufDhf6UXfsKCGcozjHHHaBRQQhKUWdOsN9LTD0y6WU+n nXh3S/pIKofFlWmQczR9UkrtVA2YVz+whETLQLPL9b2Y90ZEubNAA7yZyhexfd4izU9s 627ki4usyD/+Z8LVVanqHcg+ELKBRboAIcGvEXIbUivAd8ldndWd880iiSUWA4HaOexC FboQ== X-Gm-Message-State: AOAM533dxBQYefJkhAW7uYn/QEvGvUyNmJgMy94ZMjpvBuHtBru4g2el PD7kDGGhGVqZfjLxC6rwkxWCjGk= X-Google-Smtp-Source: ABdhPJziBKpM/iqN33lOv4N3gylj/M4b6xWwzkHJc9LwUilKQIHPk1Gw7F/oNFYL6WWGZcDAEEVvryk= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:a876:2e6a:b5f:3d90]) (user=pcc job=sendgmr) by 2002:a05:6a00:b4c:b0:481:2a:f374 with SMTP id p12-20020a056a000b4c00b00481002af374mr2413056pfo.60.1637644634614; Mon, 22 Nov 2021 21:17:14 -0800 (PST) Date: Mon, 22 Nov 2021 21:16:57 -0800 In-Reply-To: <20211123051658.3195589-1-pcc@google.com> Message-Id: <20211123051658.3195589-5-pcc@google.com> Mime-Version: 1.0 References: <20211123051658.3195589-1-pcc@google.com> X-Mailer: git-send-email 2.34.0.rc2.393.gf8c9666880-goog Subject: [PATCH v2 4/5] 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 , Colin Ian King , 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-20211122_211715_864340_D99D0786 X-CRM114-Status: GOOD ( 17.43 ) 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 --- arch/arm64/Kconfig | 1 + arch/arm64/kernel/signal.c | 5 +++++ arch/arm64/kernel/syscall.c | 3 +++ 3 files changed, 9 insertions(+) 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/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; diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 50a0f1a38e84..6de801c1af05 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -139,7 +140,9 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, goto trace_exit; } + uaccess_buffer_syscall_entry(); invoke_syscall(regs, scno, sc_nr, syscall_table); + uaccess_buffer_syscall_exit(); /* * The tracing status may have changed under our feet, so we have to From patchwork Tue Nov 23 05:16:58 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Collingbourne X-Patchwork-Id: 12693408 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 DC681C433EF for ; Tue, 23 Nov 2021 05:20:21 +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=OsVRqrmTMWG29JA0lxRoaKMQQzIGi3A/CXJl7ugpqP4=; b=bnX/4uMeVcvfURSJ2rykbkjhnm MxAV5E+6Wk/4CNKMk9pNJNWNmHTKq9PIWFBn1tpd+xMi7gd0+idrDa7DpQmTrzKUiCzxtP0pivc19 bxZmR+LBxOyxxqrUnFpMF/EouZ8e0FMFdCQ9N0C5H6twCPgoTzmIIthdFYtYAO+OJFHL+HY7kMdle U+PwQAIiwLIIGtCp704ViInT5xZj84OCPn3RwFDtX2KFoL2dVKKkDLp3gKY8Xr64s66Fg+IzlUkHR QRsJP3JhXoKGYZoQtEv9VuwRkzDlJ4KhMaDh+5XtbIKhdZxxW3rvhgAxtsweOd1UOxblICzPJMKHr et2HF8Yg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpOCR-000qGe-Ac; Tue, 23 Nov 2021 05:18:35 +0000 Received: from mail-qv1-xf49.google.com ([2607:f8b0:4864:20::f49]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpOBC-000poG-OP for linux-arm-kernel@lists.infradead.org; Tue, 23 Nov 2021 05:17:21 +0000 Received: by mail-qv1-xf49.google.com with SMTP id 1-20020ad45ba1000000b003bdfcecfe10so18184999qvq.23 for ; Mon, 22 Nov 2021 21:17:17 -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=efS21XvpUug31m8h/vGbRsh4JpXXIcnBjeaFzzUiqF4=; b=iiqPYipovhXuR+117UNtfZRyceiVgGxtpYi0ItY2mO1U0AohQ3cknEXofYrKHdU5Gd 7FJnOd5faAFGFYr9TAFsArDrA3o5RautOPi1KzPH9G8UdkabpM2aBkLnVNs9i/yC7vc+ Oa369Dh2/XwgjerEq4aukcx6dc1vKZeI+qhWxHkAFn3F99A1OklyQeD0U0goHvr+5oaz fXKqKyMw4Tf/FKaIc3CCn3ihycZFpX2oBtOPcvGmcJKiuh868h4Idh8Z1VPr0t18U6yz 60kJP8OdK7s0eSKdwCWkicoOeXARDGDSLDA25dMlUGwW1EQXgqme3Tr7HDNvrt2msFJe pQYg== 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=efS21XvpUug31m8h/vGbRsh4JpXXIcnBjeaFzzUiqF4=; b=Cff13h9FDxAp1Uqlf8sZDRKAxrAQFRcR7hs2JiTva9mLNQTaPV4POifGVz5ktES/+t GWYWjf9AH1r1DVqJSP+dFXZCvI6gltj/Ca1aXiddcIYY63t+9+jbpkMzNk2wJyLwEXv/ 76ALa6BNo4olfwA18LZ9S3yUTF8z4aOOQev5KtsvmVoXcJK0MxvkYfYtKICNZ+N6EkWR O+G03Mq3Oh1KkQX8MLkuX2M7I3EaUfbSy5gm+/g+CQqUpZ6nA8H3qCLQPaJvpyPVzfsf aaMEQEjVaI+HUNtu2meNaqJO4UWweZbCAISAefcyJSwGhxFbIGr4WTrFW6ZatashMvdS TPdQ== X-Gm-Message-State: AOAM533cqX4HLBi7cDxYtDjZT6PXSHTZSxgCm/CmN/+U49rPLYbJqSG4 RWmMfFeDdq6Df9wLrIHsfG8BPoM= X-Google-Smtp-Source: ABdhPJznKDRhXnJqv/jJFBn13R0P5Q1iPHyXDkU0aDbkudnESEgMNto88+PjGIjDzytYu6QZxkeQsX4= X-Received: from pcc-desktop.svl.corp.google.com ([2620:15c:2ce:200:a876:2e6a:b5f:3d90]) (user=pcc job=sendgmr) by 2002:a05:622a:116:: with SMTP id u22mr3131370qtw.193.1637644636718; Mon, 22 Nov 2021 21:17:16 -0800 (PST) Date: Mon, 22 Nov 2021 21:16:58 -0800 In-Reply-To: <20211123051658.3195589-1-pcc@google.com> Message-Id: <20211123051658.3195589-6-pcc@google.com> Mime-Version: 1.0 References: <20211123051658.3195589-1-pcc@google.com> X-Mailer: git-send-email 2.34.0.rc2.393.gf8c9666880-goog Subject: [PATCH v2 5/5] 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 , Colin Ian King , 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-20211122_211718_859604_A2027285 X-CRM114-Status: GOOD ( 31.21 ) 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 --- Documentation/admin-guide/index.rst | 1 + Documentation/admin-guide/uaccess-logging.rst | 149 ++++++++++++++++++ 2 files changed, 150 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..4b2b297afc00 --- /dev/null +++ b/Documentation/admin-guide/uaccess-logging.rst @@ -0,0 +1,149 @@ +.. 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. + +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; + }; + +The meaning of ``addr`` and ``size`` should be obvious. 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.