]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Jan 2020 10:28:02 +0000 (11:28 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 16 Jan 2020 10:28:02 +0000 (11:28 +0100)
added patches:
uaccess-add-non-pagefault-user-space-write-function.patch

queue-5.4/series
queue-5.4/uaccess-add-non-pagefault-user-space-write-function.patch [new file with mode: 0644]

index 875a641136ede09b6334755d1c4dd90559d7cef2..0310a0bdc4b00c37100c43d0097f13bd596a11b9 100644 (file)
@@ -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 (file)
index 0000000..d7f8c9b
--- /dev/null
@@ -0,0 +1,124 @@
+From 1d1585ca0f48fe7ed95c3571f3e4a82b2b5045dc Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <daniel@iogearbox.net>
+Date: Sat, 2 Nov 2019 00:17:56 +0100
+Subject: uaccess: Add non-pagefault user-space write function
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+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 <daniel@iogearbox.net>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Andrii Nakryiko <andriin@fb.com>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Link: https://lore.kernel.org/bpf/9df2542e68141bfa3addde631441ee45503856a8.1572649915.git.daniel@iogearbox.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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.