From: Greg Kroah-Hartman Date: Mon, 18 May 2020 15:55:10 +0000 (+0200) Subject: drop queue-4.19/bpf-restrict-bpf_trace_printk-s-s-usage-and-add-pks-pus-specifier... X-Git-Tag: v4.4.224~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e19ed765b7247180845a50c862e574408f1ca641;p=thirdparty%2Fkernel%2Fstable-queue.git drop queue-4.19/bpf-restrict-bpf_trace_printk-s-s-usage-and-add-pks-pus-specifier.patch queue-5.4/bpf-restrict-bpf_trace_printk-s-s-usage-and-add-pks-pus-specifier.patch --- diff --git a/queue-4.19/bpf-restrict-bpf_trace_printk-s-s-usage-and-add-pks-pus-specifier.patch b/queue-4.19/bpf-restrict-bpf_trace_printk-s-s-usage-and-add-pks-pus-specifier.patch deleted file mode 100644 index de7a656cfe8..00000000000 --- a/queue-4.19/bpf-restrict-bpf_trace_printk-s-s-usage-and-add-pks-pus-specifier.patch +++ /dev/null @@ -1,226 +0,0 @@ -From b2a5212fb634561bb734c6356904e37f6665b955 Mon Sep 17 00:00:00 2001 -From: Daniel Borkmann -Date: Fri, 15 May 2020 12:11:18 +0200 -Subject: bpf: Restrict bpf_trace_printk()'s %s usage and add %pks, %pus specifier - -From: Daniel Borkmann - -commit b2a5212fb634561bb734c6356904e37f6665b955 upstream. - -Usage of plain %s conversion specifier in bpf_trace_printk() suffers from the -very same issue as bpf_probe_read{,str}() helpers, that is, it is broken on -archs with overlapping address ranges. - -While the helpers have been addressed through work in 6ae08ae3dea2 ("bpf: Add -probe_read_{user, kernel} and probe_read_{user, kernel}_str helpers"), we need -an option for bpf_trace_printk() as well to fix it. - -Similarly as with the helpers, force users to make an explicit choice by adding -%pks and %pus specifier to bpf_trace_printk() which will then pick the corresponding -strncpy_from_unsafe*() variant to perform the access under KERNEL_DS or USER_DS. -The %pk* (kernel specifier) and %pu* (user specifier) can later also be extended -for other objects aside strings that are probed and printed under tracing, and -reused out of other facilities like bpf_seq_printf() or BTF based type printing. - -Existing behavior of %s for current users is still kept working for archs where it -is not broken and therefore gated through CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE. -For archs not having this property we fall-back to pick probing under KERNEL_DS as -a sensible default. - -Fixes: 8d3b7dce8622 ("bpf: add support for %s specifier to bpf_trace_printk()") -Reported-by: Linus Torvalds -Reported-by: Christoph Hellwig -Signed-off-by: Daniel Borkmann -Signed-off-by: Alexei Starovoitov -Cc: Masami Hiramatsu -Cc: Brendan Gregg -Link: https://lore.kernel.org/bpf/20200515101118.6508-4-daniel@iogearbox.net -Signed-off-by: Greg Kroah-Hartman - ---- - Documentation/core-api/printk-formats.rst | 14 ++++ - kernel/trace/bpf_trace.c | 94 +++++++++++++++++++----------- - lib/vsprintf.c | 12 +++ - 3 files changed, 88 insertions(+), 32 deletions(-) - ---- a/Documentation/core-api/printk-formats.rst -+++ b/Documentation/core-api/printk-formats.rst -@@ -94,6 +94,20 @@ used when printing stack backtraces. The - consideration the effect of compiler optimisations which may occur - when tail-calls are used and marked with the noreturn GCC attribute. - -+Probed Pointers from BPF / tracing -+---------------------------------- -+ -+:: -+ -+ %pks kernel string -+ %pus user string -+ -+The ``k`` and ``u`` specifiers are used for printing prior probed memory from -+either kernel memory (k) or user memory (u). The subsequent ``s`` specifier -+results in printing a string. For direct use in regular vsnprintf() the (k) -+and (u) annotation is ignored, however, when used out of BPF's bpf_trace_printk(), -+for example, it reads the memory it is pointing to without faulting. -+ - Kernel Pointers - --------------- - ---- a/kernel/trace/bpf_trace.c -+++ b/kernel/trace/bpf_trace.c -@@ -158,17 +158,15 @@ static const struct bpf_func_proto *bpf_ - - /* - * Only limited trace_printk() conversion specifiers allowed: -- * %d %i %u %x %ld %li %lu %lx %lld %lli %llu %llx %p %s -+ * %d %i %u %x %ld %li %lu %lx %lld %lli %llu %llx %p %pks %pus %s - */ - BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1, - u64, arg2, u64, arg3) - { -+ int i, mod[3] = {}, fmt_cnt = 0; -+ char buf[64], fmt_ptype; -+ void *unsafe_ptr = NULL; - bool str_seen = false; -- int mod[3] = {}; -- int fmt_cnt = 0; -- u64 unsafe_addr; -- char buf[64]; -- int i; - - /* - * bpf_check()->check_func_arg()->check_stack_boundary() -@@ -194,40 +192,71 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt - if (fmt[i] == 'l') { - mod[fmt_cnt]++; - i++; -- } else if (fmt[i] == 'p' || fmt[i] == 's') { -+ } else if (fmt[i] == 'p') { - mod[fmt_cnt]++; -+ if ((fmt[i + 1] == 'k' || -+ fmt[i + 1] == 'u') && -+ fmt[i + 2] == 's') { -+ fmt_ptype = fmt[i + 1]; -+ i += 2; -+ goto fmt_str; -+ } -+ - /* disallow any further format extensions */ - if (fmt[i + 1] != 0 && - !isspace(fmt[i + 1]) && - !ispunct(fmt[i + 1])) - return -EINVAL; -- fmt_cnt++; -- if (fmt[i] == 's') { -- if (str_seen) -- /* allow only one '%s' per fmt string */ -- return -EINVAL; -- str_seen = true; -- -- switch (fmt_cnt) { -- case 1: -- unsafe_addr = arg1; -- arg1 = (long) buf; -- break; -- case 2: -- unsafe_addr = arg2; -- arg2 = (long) buf; -- break; -- case 3: -- unsafe_addr = arg3; -- arg3 = (long) buf; -- break; -- } -- buf[0] = 0; -- strncpy_from_unsafe(buf, -- (void *) (long) unsafe_addr, -+ -+ goto fmt_next; -+ } else if (fmt[i] == 's') { -+ mod[fmt_cnt]++; -+ fmt_ptype = fmt[i]; -+fmt_str: -+ if (str_seen) -+ /* allow only one '%s' per fmt string */ -+ return -EINVAL; -+ str_seen = true; -+ -+ if (fmt[i + 1] != 0 && -+ !isspace(fmt[i + 1]) && -+ !ispunct(fmt[i + 1])) -+ return -EINVAL; -+ -+ switch (fmt_cnt) { -+ case 0: -+ unsafe_ptr = (void *)(long)arg1; -+ arg1 = (long)buf; -+ break; -+ case 1: -+ unsafe_ptr = (void *)(long)arg2; -+ arg2 = (long)buf; -+ break; -+ case 2: -+ unsafe_ptr = (void *)(long)arg3; -+ arg3 = (long)buf; -+ break; -+ } -+ -+ buf[0] = 0; -+ switch (fmt_ptype) { -+ case 's': -+#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE -+ strncpy_from_unsafe(buf, unsafe_ptr, - sizeof(buf)); -+ break; -+#endif -+ case 'k': -+ strncpy_from_unsafe_strict(buf, unsafe_ptr, -+ sizeof(buf)); -+ break; -+ case 'u': -+ strncpy_from_unsafe_user(buf, -+ (__force void __user *)unsafe_ptr, -+ sizeof(buf)); -+ break; - } -- continue; -+ goto fmt_next; - } - - if (fmt[i] == 'l') { -@@ -238,6 +267,7 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt - if (fmt[i] != 'i' && fmt[i] != 'd' && - fmt[i] != 'u' && fmt[i] != 'x') - return -EINVAL; -+fmt_next: - fmt_cnt++; - } - ---- a/lib/vsprintf.c -+++ b/lib/vsprintf.c -@@ -1845,6 +1845,10 @@ static char *ptr_to_id(char *buf, char * - * C full compatible string - * - * - 'x' For printing the address. Equivalent to "%lx". -+ * - '[ku]s' For a BPF/tracing related format specifier, e.g. used out of -+ * bpf_trace_printk() where [ku] prefix specifies either kernel (k) -+ * or user (u) memory to probe, and: -+ * s a string, equivalent to "%s" on direct vsnprintf() use - * - * ** When making changes please also update: - * Documentation/core-api/printk-formats.rst -@@ -1970,6 +1974,14 @@ char *pointer(const char *fmt, char *buf - break; - case 'x': - return pointer_string(buf, end, ptr, spec); -+ case 'u': -+ case 'k': -+ switch (fmt[1]) { -+ case 's': -+ return string(buf, end, ptr, spec); -+ default: -+ return error_string(buf, end, "(einval)", spec); -+ } - } - - /* default is to _not_ leak addresses, hash before printing */ diff --git a/queue-4.19/series b/queue-4.19/series index 356e0cf4e3c..cd83b1aaa00 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -77,5 +77,4 @@ arm-dts-r8a73a4-add-missing-cmt1-interrupts.patch arm64-dts-renesas-r8a77980-fix-ipmmu-vip-nodes.patch arm-dts-r8a7740-add-missing-extal2-to-cpg-node.patch kvm-x86-fix-off-by-one-error-in-kvm_vcpu_ioctl_x86_setup_mce.patch -bpf-restrict-bpf_trace_printk-s-s-usage-and-add-pks-pus-specifier.patch makefile-disallow-data-races-on-gcc-10-as-well.patch diff --git a/queue-5.4/bpf-restrict-bpf_trace_printk-s-s-usage-and-add-pks-pus-specifier.patch b/queue-5.4/bpf-restrict-bpf_trace_printk-s-s-usage-and-add-pks-pus-specifier.patch deleted file mode 100644 index 66a1ee62c23..00000000000 --- a/queue-5.4/bpf-restrict-bpf_trace_printk-s-s-usage-and-add-pks-pus-specifier.patch +++ /dev/null @@ -1,226 +0,0 @@ -From b2a5212fb634561bb734c6356904e37f6665b955 Mon Sep 17 00:00:00 2001 -From: Daniel Borkmann -Date: Fri, 15 May 2020 12:11:18 +0200 -Subject: bpf: Restrict bpf_trace_printk()'s %s usage and add %pks, %pus specifier - -From: Daniel Borkmann - -commit b2a5212fb634561bb734c6356904e37f6665b955 upstream. - -Usage of plain %s conversion specifier in bpf_trace_printk() suffers from the -very same issue as bpf_probe_read{,str}() helpers, that is, it is broken on -archs with overlapping address ranges. - -While the helpers have been addressed through work in 6ae08ae3dea2 ("bpf: Add -probe_read_{user, kernel} and probe_read_{user, kernel}_str helpers"), we need -an option for bpf_trace_printk() as well to fix it. - -Similarly as with the helpers, force users to make an explicit choice by adding -%pks and %pus specifier to bpf_trace_printk() which will then pick the corresponding -strncpy_from_unsafe*() variant to perform the access under KERNEL_DS or USER_DS. -The %pk* (kernel specifier) and %pu* (user specifier) can later also be extended -for other objects aside strings that are probed and printed under tracing, and -reused out of other facilities like bpf_seq_printf() or BTF based type printing. - -Existing behavior of %s for current users is still kept working for archs where it -is not broken and therefore gated through CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE. -For archs not having this property we fall-back to pick probing under KERNEL_DS as -a sensible default. - -Fixes: 8d3b7dce8622 ("bpf: add support for %s specifier to bpf_trace_printk()") -Reported-by: Linus Torvalds -Reported-by: Christoph Hellwig -Signed-off-by: Daniel Borkmann -Signed-off-by: Alexei Starovoitov -Cc: Masami Hiramatsu -Cc: Brendan Gregg -Link: https://lore.kernel.org/bpf/20200515101118.6508-4-daniel@iogearbox.net -Signed-off-by: Greg Kroah-Hartman - ---- - Documentation/core-api/printk-formats.rst | 14 ++++ - kernel/trace/bpf_trace.c | 94 +++++++++++++++++++----------- - lib/vsprintf.c | 12 +++ - 3 files changed, 88 insertions(+), 32 deletions(-) - ---- a/Documentation/core-api/printk-formats.rst -+++ b/Documentation/core-api/printk-formats.rst -@@ -110,6 +110,20 @@ used when printing stack backtraces. The - consideration the effect of compiler optimisations which may occur - when tail-calls are used and marked with the noreturn GCC attribute. - -+Probed Pointers from BPF / tracing -+---------------------------------- -+ -+:: -+ -+ %pks kernel string -+ %pus user string -+ -+The ``k`` and ``u`` specifiers are used for printing prior probed memory from -+either kernel memory (k) or user memory (u). The subsequent ``s`` specifier -+results in printing a string. For direct use in regular vsnprintf() the (k) -+and (u) annotation is ignored, however, when used out of BPF's bpf_trace_printk(), -+for example, it reads the memory it is pointing to without faulting. -+ - Kernel Pointers - --------------- - ---- a/kernel/trace/bpf_trace.c -+++ b/kernel/trace/bpf_trace.c -@@ -209,17 +209,15 @@ static const struct bpf_func_proto *bpf_ - - /* - * Only limited trace_printk() conversion specifiers allowed: -- * %d %i %u %x %ld %li %lu %lx %lld %lli %llu %llx %p %s -+ * %d %i %u %x %ld %li %lu %lx %lld %lli %llu %llx %p %pks %pus %s - */ - BPF_CALL_5(bpf_trace_printk, char *, fmt, u32, fmt_size, u64, arg1, - u64, arg2, u64, arg3) - { -+ int i, mod[3] = {}, fmt_cnt = 0; -+ char buf[64], fmt_ptype; -+ void *unsafe_ptr = NULL; - bool str_seen = false; -- int mod[3] = {}; -- int fmt_cnt = 0; -- u64 unsafe_addr; -- char buf[64]; -- int i; - - /* - * bpf_check()->check_func_arg()->check_stack_boundary() -@@ -245,40 +243,71 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt - if (fmt[i] == 'l') { - mod[fmt_cnt]++; - i++; -- } else if (fmt[i] == 'p' || fmt[i] == 's') { -+ } else if (fmt[i] == 'p') { - mod[fmt_cnt]++; -+ if ((fmt[i + 1] == 'k' || -+ fmt[i + 1] == 'u') && -+ fmt[i + 2] == 's') { -+ fmt_ptype = fmt[i + 1]; -+ i += 2; -+ goto fmt_str; -+ } -+ - /* disallow any further format extensions */ - if (fmt[i + 1] != 0 && - !isspace(fmt[i + 1]) && - !ispunct(fmt[i + 1])) - return -EINVAL; -- fmt_cnt++; -- if (fmt[i] == 's') { -- if (str_seen) -- /* allow only one '%s' per fmt string */ -- return -EINVAL; -- str_seen = true; -- -- switch (fmt_cnt) { -- case 1: -- unsafe_addr = arg1; -- arg1 = (long) buf; -- break; -- case 2: -- unsafe_addr = arg2; -- arg2 = (long) buf; -- break; -- case 3: -- unsafe_addr = arg3; -- arg3 = (long) buf; -- break; -- } -- buf[0] = 0; -- strncpy_from_unsafe(buf, -- (void *) (long) unsafe_addr, -+ -+ goto fmt_next; -+ } else if (fmt[i] == 's') { -+ mod[fmt_cnt]++; -+ fmt_ptype = fmt[i]; -+fmt_str: -+ if (str_seen) -+ /* allow only one '%s' per fmt string */ -+ return -EINVAL; -+ str_seen = true; -+ -+ if (fmt[i + 1] != 0 && -+ !isspace(fmt[i + 1]) && -+ !ispunct(fmt[i + 1])) -+ return -EINVAL; -+ -+ switch (fmt_cnt) { -+ case 0: -+ unsafe_ptr = (void *)(long)arg1; -+ arg1 = (long)buf; -+ break; -+ case 1: -+ unsafe_ptr = (void *)(long)arg2; -+ arg2 = (long)buf; -+ break; -+ case 2: -+ unsafe_ptr = (void *)(long)arg3; -+ arg3 = (long)buf; -+ break; -+ } -+ -+ buf[0] = 0; -+ switch (fmt_ptype) { -+ case 's': -+#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE -+ strncpy_from_unsafe(buf, unsafe_ptr, - sizeof(buf)); -+ break; -+#endif -+ case 'k': -+ strncpy_from_unsafe_strict(buf, unsafe_ptr, -+ sizeof(buf)); -+ break; -+ case 'u': -+ strncpy_from_unsafe_user(buf, -+ (__force void __user *)unsafe_ptr, -+ sizeof(buf)); -+ break; - } -- continue; -+ goto fmt_next; - } - - if (fmt[i] == 'l') { -@@ -289,6 +318,7 @@ BPF_CALL_5(bpf_trace_printk, char *, fmt - if (fmt[i] != 'i' && fmt[i] != 'd' && - fmt[i] != 'u' && fmt[i] != 'x') - return -EINVAL; -+fmt_next: - fmt_cnt++; - } - ---- a/lib/vsprintf.c -+++ b/lib/vsprintf.c -@@ -2109,6 +2109,10 @@ static char *kobject_string(char *buf, c - * c major compatible string - * C full compatible string - * - 'x' For printing the address. Equivalent to "%lx". -+ * - '[ku]s' For a BPF/tracing related format specifier, e.g. used out of -+ * bpf_trace_printk() where [ku] prefix specifies either kernel (k) -+ * or user (u) memory to probe, and: -+ * s a string, equivalent to "%s" on direct vsnprintf() use - * - * ** When making changes please also update: - * Documentation/core-api/printk-formats.rst -@@ -2187,6 +2191,14 @@ char *pointer(const char *fmt, char *buf - return kobject_string(buf, end, ptr, spec, fmt); - case 'x': - return pointer_string(buf, end, ptr, spec); -+ case 'u': -+ case 'k': -+ switch (fmt[1]) { -+ case 's': -+ return string(buf, end, ptr, spec); -+ default: -+ return error_string(buf, end, "(einval)", spec); -+ } - } - - /* default is to _not_ leak addresses, hash before printing */ diff --git a/queue-5.4/series b/queue-5.4/series index df683c45c5c..cd414638659 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -141,5 +141,4 @@ arm-dts-r8a7740-add-missing-extal2-to-cpg-node.patch sunrpc-revert-241b1f419f0e-sunrpc-remove-xdr_buf_trim.patch bpf-fix-sk_psock-refcnt-leak-when-receiving-message.patch kvm-x86-fix-off-by-one-error-in-kvm_vcpu_ioctl_x86_setup_mce.patch -bpf-restrict-bpf_trace_printk-s-s-usage-and-add-pks-pus-specifier.patch makefile-disallow-data-races-on-gcc-10-as-well.patch