From: Greg Kroah-Hartman Date: Thu, 16 Jan 2020 10:28:02 +0000 (+0100) Subject: 5.4-stable patches X-Git-Tag: v4.14.166~19 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b340af6b7777cd531fe0aab6efc83f6fe9e15e01;p=thirdparty%2Fkernel%2Fstable-queue.git 5.4-stable patches added patches: uaccess-add-non-pagefault-user-space-write-function.patch --- diff --git a/queue-5.4/series b/queue-5.4/series index 875a641136e..0310a0bdc4b 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -74,6 +74,7 @@ rdma-hns-bugfix-for-qpc-cqc-timer-configuration.patch rdma-remove-nes-abi-header.patch rdma-mlx5-return-proper-error-value.patch rdma-srpt-report-the-scsi-residual-to-the-initiator.patch +uaccess-add-non-pagefault-user-space-write-function.patch bpf-make-use-of-probe_user_write-in-probe-write-helper.patch bpf-skmsg-fix-potential-psock-null-pointer-dereference.patch bpf-support-pre-2.25-binutils-objcopy-for-vmlinux-btf.patch diff --git a/queue-5.4/uaccess-add-non-pagefault-user-space-write-function.patch b/queue-5.4/uaccess-add-non-pagefault-user-space-write-function.patch new file mode 100644 index 00000000000..d7f8c9b9fea --- /dev/null +++ b/queue-5.4/uaccess-add-non-pagefault-user-space-write-function.patch @@ -0,0 +1,124 @@ +From 1d1585ca0f48fe7ed95c3571f3e4a82b2b5045dc Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Sat, 2 Nov 2019 00:17:56 +0100 +Subject: uaccess: Add non-pagefault user-space write function + +From: Daniel Borkmann + +commit 1d1585ca0f48fe7ed95c3571f3e4a82b2b5045dc upstream. + +Commit 3d7081822f7f ("uaccess: Add non-pagefault user-space read functions") +missed to add probe write function, therefore factor out a probe_write_common() +helper with most logic of probe_kernel_write() except setting KERNEL_DS, and +add a new probe_user_write() helper so it can be used from BPF side. + +Again, on some archs, the user address space and kernel address space can +co-exist and be overlapping, so in such case, setting KERNEL_DS would mean +that the given address is treated as being in kernel address space. + +Signed-off-by: Daniel Borkmann +Signed-off-by: Alexei Starovoitov +Acked-by: Andrii Nakryiko +Cc: Masami Hiramatsu +Link: https://lore.kernel.org/bpf/9df2542e68141bfa3addde631441ee45503856a8.1572649915.git.daniel@iogearbox.net +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/uaccess.h | 12 ++++++++++++ + mm/maccess.c | 45 +++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 53 insertions(+), 4 deletions(-) + +--- a/include/linux/uaccess.h ++++ b/include/linux/uaccess.h +@@ -337,6 +337,18 @@ extern long __probe_user_read(void *dst, + extern long notrace probe_kernel_write(void *dst, const void *src, size_t size); + extern long notrace __probe_kernel_write(void *dst, const void *src, size_t size); + ++/* ++ * probe_user_write(): safely attempt to write to a location in user space ++ * @dst: address to write to ++ * @src: pointer to the data that shall be written ++ * @size: size of the data chunk ++ * ++ * Safely write to address @dst from the buffer at @src. If a kernel fault ++ * happens, handle that and return -EFAULT. ++ */ ++extern long notrace probe_user_write(void __user *dst, const void *src, size_t size); ++extern long notrace __probe_user_write(void __user *dst, const void *src, size_t size); ++ + extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count); + extern long strncpy_from_unsafe_user(char *dst, const void __user *unsafe_addr, + long count); +--- a/mm/maccess.c ++++ b/mm/maccess.c +@@ -18,6 +18,18 @@ probe_read_common(void *dst, const void + return ret ? -EFAULT : 0; + } + ++static __always_inline long ++probe_write_common(void __user *dst, const void *src, size_t size) ++{ ++ long ret; ++ ++ pagefault_disable(); ++ ret = __copy_to_user_inatomic(dst, src, size); ++ pagefault_enable(); ++ ++ return ret ? -EFAULT : 0; ++} ++ + /** + * probe_kernel_read(): safely attempt to read from a kernel-space location + * @dst: pointer to the buffer that shall take the data +@@ -85,6 +97,7 @@ EXPORT_SYMBOL_GPL(probe_user_read); + * Safely write to address @dst from the buffer at @src. If a kernel fault + * happens, handle that and return -EFAULT. + */ ++ + long __weak probe_kernel_write(void *dst, const void *src, size_t size) + __attribute__((alias("__probe_kernel_write"))); + +@@ -94,15 +107,39 @@ long __probe_kernel_write(void *dst, con + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); +- pagefault_disable(); +- ret = __copy_to_user_inatomic((__force void __user *)dst, src, size); +- pagefault_enable(); ++ ret = probe_write_common((__force void __user *)dst, src, size); + set_fs(old_fs); + +- return ret ? -EFAULT : 0; ++ return ret; + } + EXPORT_SYMBOL_GPL(probe_kernel_write); + ++/** ++ * probe_user_write(): safely attempt to write to a user-space location ++ * @dst: address to write to ++ * @src: pointer to the data that shall be written ++ * @size: size of the data chunk ++ * ++ * Safely write to address @dst from the buffer at @src. If a kernel fault ++ * happens, handle that and return -EFAULT. ++ */ ++ ++long __weak probe_user_write(void __user *dst, const void *src, size_t size) ++ __attribute__((alias("__probe_user_write"))); ++ ++long __probe_user_write(void __user *dst, const void *src, size_t size) ++{ ++ long ret = -EFAULT; ++ mm_segment_t old_fs = get_fs(); ++ ++ set_fs(USER_DS); ++ if (access_ok(dst, size)) ++ ret = probe_write_common(dst, src, size); ++ set_fs(old_fs); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(probe_user_write); + + /** + * strncpy_from_unsafe: - Copy a NUL terminated string from unsafe address.