commit 9de1fec50b23117f0a19f7609cc837ca72e764a6 upstream.
This is an adaptation of parts from the above commit to kernel 5.4.
Allow Kprobes to access userspace data correctly in architectures with no overlap between kernel and userspace addresses.
Cc: stable@vger.kernel.org # 5.4.x Signed-off-by: Tsahi Zidenberg tsahee@amazon.com --- kernel/trace/trace_kprobe.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 233322c77b76..cbd72a1c9530 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -1043,6 +1043,11 @@ fetch_store_strlen(unsigned long addr) int ret, len = 0; u8 c; +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + if (addr < TASK_SIZE) + return fetch_store_strlen_user(addr); +#endif + do { ret = probe_kernel_read(&c, (u8 *)addr + len, 1); len++; @@ -1071,6 +1076,11 @@ fetch_store_string(unsigned long addr, void *dest, void *base) void *__dest; long ret; +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + if (addr < TASK_SIZE) + return fetch_store_string_user(addr, dest, base); +#endif + if (unlikely(!maxlen)) return -ENOMEM; @@ -1114,6 +1124,11 @@ fetch_store_string_user(unsigned long addr, void *dest, void *base) static nokprobe_inline int probe_mem_read(void *dest, void *src, size_t size) { +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + if ((unsigned long)src < TASK_SIZE) + return probe_mem_read_user(dest, src, size); +#endif + return probe_kernel_read(dest, src, size); }