commit 8d92db5c04d10381f4db70ed99b1b576f5db18a7 upstream. This is an adaptation of parts from above commit to kernel 5.4. bpf_probe_read{,str}() BPF helpers are broken on arm64, where user addresses cannot be accessed with normal kernelspace access. Upstream solution got into v5.8 and cannot directly be cherry picked. We implement the same mechanism in kernel 5.4. Detection is only enabled for machines with non-overlapping address spaces using CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE from commits: commit 0ebeea8ca8a4 ("bpf: Restrict bpf_probe_read{, str}() only to archs where they work") commit d195b1d1d119 ("powerpc/bpf: Enable bpf_probe_read{, str}() on powerpc again") To generally fix the issue, upstream includes new BPF helpers: bpf_probe_read_{user,kernel}_str(). For details on them, see commit 6ae08ae3dea2 ("bpf: Add probe_read_{user, kernel} and probe_read_{user, kernel}_str helpers") Cc: <stable@xxxxxxxxxxxxxxx> # 5.4.x Signed-off-by: Tsahi Zidenberg <tsahee@xxxxxxxxxx> --- arch/arm/Kconfig | 1 + arch/arm64/Kconfig | 1 + arch/powerpc/Kconfig | 1 + arch/x86/Kconfig | 1 + init/Kconfig | 3 +++ kernel/trace/bpf_trace.c | 18 ++++++++++++++++++ 6 files changed, 25 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9aa88715f196..70f4057fb5b0 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -14,6 +14,7 @@ config ARM select ARCH_HAS_KEEPINITRD select ARCH_HAS_KCOV select ARCH_HAS_MEMBARRIER_SYNC_CORE + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE select ARCH_HAS_PTE_SPECIAL if ARM_LPAE select ARCH_HAS_PHYS_TO_DMA select ARCH_HAS_SETUP_DMA_OPS diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 9c8ea5939865..a8c49916ab8c 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -22,6 +22,7 @@ config ARM64 select ARCH_HAS_KCOV select ARCH_HAS_KEEPINITRD select ARCH_HAS_MEMBARRIER_SYNC_CORE + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE select ARCH_HAS_PTE_DEVMAP select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_SETUP_DMA_OPS diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index c4cbb65e742f..c50bfab7930b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -129,6 +129,7 @@ config PPC select ARCH_HAS_MMIOWB if PPC64 select ARCH_HAS_PHYS_TO_DMA select ARCH_HAS_PMEM_API + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE select ARCH_HAS_PTE_DEVMAP if PPC_BOOK3S_64 select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_MEMBARRIER_CALLBACKS diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 8ef85139553f..b9f666db10c1 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -70,6 +70,7 @@ config X86 select ARCH_HAS_KCOV if X86_64 select ARCH_HAS_MEM_ENCRYPT select ARCH_HAS_MEMBARRIER_SYNC_CORE + select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE select ARCH_HAS_PMEM_API if X86_64 select ARCH_HAS_PTE_DEVMAP if X86_64 select ARCH_HAS_PTE_SPECIAL diff --git a/init/Kconfig b/init/Kconfig index 96fc45d1b686..1781810d1501 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2210,6 +2210,9 @@ config ASN1 source "kernel/Kconfig.locks" +config ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + bool + config ARCH_HAS_SYNC_CORE_BEFORE_USERMODE bool diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 74c1db7178cf..ef534ad3f94d 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -142,6 +142,15 @@ BPF_CALL_3(bpf_probe_read, void *, dst, u32, size, const void *, unsafe_ptr) { int ret; +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + if ((unsigned long)unsafe_ptr < TASK_SIZE) { + ret = probe_user_read(dst, unsafe_ptr, size); + if (unlikely(ret < 0)) + goto out; + return ret; + } +#endif + ret = security_locked_down(LOCKDOWN_BPF_READ); if (ret < 0) goto out; @@ -588,6 +597,15 @@ BPF_CALL_3(bpf_probe_read_str, void *, dst, u32, size, { int ret; +#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE + if ((unsigned long)unsafe_ptr < TASK_SIZE) { + ret = strncpy_from_unsafe_user(dst, (__force void __user *)unsafe_ptr, size); + if (unlikely(ret < 0)) + goto out; + return ret; + } +#endif + ret = security_locked_down(LOCKDOWN_BPF_READ); if (ret < 0) goto out; -- 2.25.1