From: Christophe Leroy <christophe.leroy@c-s.fr> To: Kees Cook <keescook@chromium.org>, Andrew Morton <akpm@linux-foundation.org>, Benjamin Herrenschmidt <benh@kernel.crashing.org>, Paul Mackerras <paulus@samba.org>, Michael Ellerman <mpe@ellerman.id.au>, Mike Rapoport <rppt@linux.ibm.com> Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-mm@kvack.org Subject: [PATCH v2 1/2] mm: add probe_user_read() Date: Tue, 8 Jan 2019 07:37:44 +0000 (UTC) [thread overview] Message-ID: <0b0db24e18063076e9d9f4e376994af83da05456.1546932949.git.christophe.leroy@c-s.fr> (raw) In powerpc code, there are several places implementing safe access to user data. This is sometimes implemented using probe_kernel_address() with additional access_ok() verification, sometimes with get_user() enclosed in a pagefault_disable()/enable() pair, etc. : show_user_instructions() bad_stack_expansion() p9_hmi_special_emu() fsl_pci_mcheck_exception() read_user_stack_64() read_user_stack_32() on PPC64 read_user_stack_32() on PPC32 power_pmu_bhrb_to() In the same spirit as probe_kernel_read(), this patch adds probe_user_read(). probe_user_read() does the same as probe_kernel_read() but first checks that it is really a user address. Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> --- v2: Added "Returns:" comment and removed probe_user_address() Changes since RFC: Made a static inline function instead of weak function as recommended by Kees. include/linux/uaccess.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 37b226e8df13..07f4f0ed69bc 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -263,6 +263,40 @@ extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count); #define probe_kernel_address(addr, retval) \ probe_kernel_read(&retval, addr, sizeof(retval)) +/** + * probe_user_read(): safely attempt to read from a user location + * @dst: pointer to the buffer that shall take the data + * @src: address to read from + * @size: size of the data chunk + * + * Returns: 0 on success, -EFAULT on error. + * + * Safely read from address @src to the buffer at @dst. If a kernel fault + * happens, handle that and return -EFAULT. + * + * We ensure that the copy_from_user is executed in atomic context so that + * do_page_fault() doesn't attempt to take mmap_sem. This makes + * probe_user_read() suitable for use within regions where the caller + * already holds mmap_sem, or other locks which nest inside mmap_sem. + */ + +#ifndef probe_user_read +static __always_inline long probe_user_read(void *dst, const void __user *src, + size_t size) +{ + long ret; + + if (!access_ok(src, size)) + return -EFAULT; + + pagefault_disable(); + ret = __copy_from_user_inatomic(dst, src, size); + pagefault_enable(); + + return ret ? -EFAULT : 0; +} +#endif + #ifndef user_access_begin #define user_access_begin(ptr,len) access_ok(ptr, len) #define user_access_end() do { } while (0) -- 2.13.3
WARNING: multiple messages have this Message-ID (diff)
From: Christophe Leroy <christophe.leroy@c-s.fr> To: Kees Cook <keescook@chromium.org>, Andrew Morton <akpm@linux-foundation.org>, Benjamin Herrenschmidt <benh@kernel.crashing.org>, Paul Mackerras <paulus@samba.org>, Michael Ellerman <mpe@ellerman.id.au>, Mike Rapoport <rppt@linux.ibm.com> Cc: linux-mm@kvack.org, linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 1/2] mm: add probe_user_read() Date: Tue, 8 Jan 2019 07:37:44 +0000 (UTC) [thread overview] Message-ID: <0b0db24e18063076e9d9f4e376994af83da05456.1546932949.git.christophe.leroy@c-s.fr> (raw) In powerpc code, there are several places implementing safe access to user data. This is sometimes implemented using probe_kernel_address() with additional access_ok() verification, sometimes with get_user() enclosed in a pagefault_disable()/enable() pair, etc. : show_user_instructions() bad_stack_expansion() p9_hmi_special_emu() fsl_pci_mcheck_exception() read_user_stack_64() read_user_stack_32() on PPC64 read_user_stack_32() on PPC32 power_pmu_bhrb_to() In the same spirit as probe_kernel_read(), this patch adds probe_user_read(). probe_user_read() does the same as probe_kernel_read() but first checks that it is really a user address. Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr> --- v2: Added "Returns:" comment and removed probe_user_address() Changes since RFC: Made a static inline function instead of weak function as recommended by Kees. include/linux/uaccess.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 37b226e8df13..07f4f0ed69bc 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -263,6 +263,40 @@ extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count); #define probe_kernel_address(addr, retval) \ probe_kernel_read(&retval, addr, sizeof(retval)) +/** + * probe_user_read(): safely attempt to read from a user location + * @dst: pointer to the buffer that shall take the data + * @src: address to read from + * @size: size of the data chunk + * + * Returns: 0 on success, -EFAULT on error. + * + * Safely read from address @src to the buffer at @dst. If a kernel fault + * happens, handle that and return -EFAULT. + * + * We ensure that the copy_from_user is executed in atomic context so that + * do_page_fault() doesn't attempt to take mmap_sem. This makes + * probe_user_read() suitable for use within regions where the caller + * already holds mmap_sem, or other locks which nest inside mmap_sem. + */ + +#ifndef probe_user_read +static __always_inline long probe_user_read(void *dst, const void __user *src, + size_t size) +{ + long ret; + + if (!access_ok(src, size)) + return -EFAULT; + + pagefault_disable(); + ret = __copy_from_user_inatomic(dst, src, size); + pagefault_enable(); + + return ret ? -EFAULT : 0; +} +#endif + #ifndef user_access_begin #define user_access_begin(ptr,len) access_ok(ptr, len) #define user_access_end() do { } while (0) -- 2.13.3
next reply other threads:[~2019-01-08 7:37 UTC|newest] Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-01-08 7:37 Christophe Leroy [this message] 2019-01-08 7:37 ` [PATCH v2 1/2] mm: add probe_user_read() Christophe Leroy 2019-01-08 7:37 ` [PATCH v2 2/2] powerpc: use probe_user_read() Christophe Leroy 2019-01-08 7:37 ` Christophe Leroy 2019-01-08 9:04 ` David Hildenbrand 2019-01-08 9:04 ` David Hildenbrand 2019-01-08 9:19 ` Christophe Leroy 2019-01-08 9:19 ` Christophe Leroy 2019-01-08 9:37 ` Christophe Leroy 2019-01-08 9:37 ` Christophe Leroy 2019-01-08 9:58 ` Russell Currey 2019-01-08 9:58 ` Russell Currey 2019-01-08 9:58 ` Russell Currey 2019-01-08 7:51 ` [PATCH v2 1/2] mm: add probe_user_read() Mike Rapoport 2019-01-08 7:51 ` Mike Rapoport 2019-01-08 19:48 ` Andrew Morton 2019-01-08 19:48 ` Andrew Morton 2019-01-08 21:11 ` Christophe Leroy 2019-01-08 21:11 ` Christophe Leroy 2019-01-08 21:14 ` Kees Cook 2019-01-08 21:14 ` Kees Cook 2019-01-08 21:14 ` Kees Cook
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=0b0db24e18063076e9d9f4e376994af83da05456.1546932949.git.christophe.leroy@c-s.fr \ --to=christophe.leroy@c-s.fr \ --cc=akpm@linux-foundation.org \ --cc=benh@kernel.crashing.org \ --cc=keescook@chromium.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mm@kvack.org \ --cc=linuxppc-dev@lists.ozlabs.org \ --cc=mpe@ellerman.id.au \ --cc=paulus@samba.org \ --cc=rppt@linux.ibm.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.