From: Greg Kroah-Hartman Date: Tue, 27 Mar 2018 15:39:24 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v4.15.14~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=82d2cdc79e6573b88379ef444bdd9237a2c29156;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: bpf-skip-unnecessary-capability-check.patch bpf-x64-increase-number-of-passes.patch kbuild-disable-clang-s-default-use-of-fmerge-all-constants.patch --- diff --git a/queue-4.4/bpf-skip-unnecessary-capability-check.patch b/queue-4.4/bpf-skip-unnecessary-capability-check.patch new file mode 100644 index 00000000000..a01b7d0e11e --- /dev/null +++ b/queue-4.4/bpf-skip-unnecessary-capability-check.patch @@ -0,0 +1,37 @@ +From 0fa4fe85f4724fff89b09741c437cbee9cf8b008 Mon Sep 17 00:00:00 2001 +From: Chenbo Feng +Date: Mon, 19 Mar 2018 17:57:27 -0700 +Subject: bpf: skip unnecessary capability check + +From: Chenbo Feng + +commit 0fa4fe85f4724fff89b09741c437cbee9cf8b008 upstream. + +The current check statement in BPF syscall will do a capability check +for CAP_SYS_ADMIN before checking sysctl_unprivileged_bpf_disabled. This +code path will trigger unnecessary security hooks on capability checking +and cause false alarms on unprivileged process trying to get CAP_SYS_ADMIN +access. This can be resolved by simply switch the order of the statement +and CAP_SYS_ADMIN is not required anyway if unprivileged bpf syscall is +allowed. + +Signed-off-by: Chenbo Feng +Acked-by: Lorenzo Colitti +Signed-off-by: Daniel Borkmann +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/bpf/syscall.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/kernel/bpf/syscall.c ++++ b/kernel/bpf/syscall.c +@@ -673,7 +673,7 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf + union bpf_attr attr = {}; + int err; + +- if (!capable(CAP_SYS_ADMIN) && sysctl_unprivileged_bpf_disabled) ++ if (sysctl_unprivileged_bpf_disabled && !capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (!access_ok(VERIFY_READ, uattr, 1)) diff --git a/queue-4.4/bpf-x64-increase-number-of-passes.patch b/queue-4.4/bpf-x64-increase-number-of-passes.patch new file mode 100644 index 00000000000..b4593d977bd --- /dev/null +++ b/queue-4.4/bpf-x64-increase-number-of-passes.patch @@ -0,0 +1,54 @@ +From 6007b080d2e2adb7af22bf29165f0594ea12b34c Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 7 Mar 2018 22:10:01 +0100 +Subject: bpf, x64: increase number of passes + +From: Daniel Borkmann + +commit 6007b080d2e2adb7af22bf29165f0594ea12b34c upstream. + +In Cilium some of the main programs we run today are hitting 9 passes +on x64's JIT compiler, and we've had cases already where we surpassed +the limit where the JIT then punts the program to the interpreter +instead, leading to insertion failures due to CONFIG_BPF_JIT_ALWAYS_ON +or insertion failures due to the prog array owner being JITed but the +program to insert not (both must have the same JITed/non-JITed property). + +One concrete case the program image shrunk from 12,767 bytes down to +10,288 bytes where the image converged after 16 steps. I've measured +that this took 340us in the JIT until it converges on my i7-6600U. Thus, +increase the original limit we had from day one where the JIT covered +cBPF only back then before we run into the case (as similar with the +complexity limit) where we trip over this and hit program rejections. +Also add a cond_resched() into the compilation loop, the JIT process +runs without any locks and may sleep anyway. + +Signed-off-by: Daniel Borkmann +Acked-by: Alexei Starovoitov +Reviewed-by: Eric Dumazet +Signed-off-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/net/bpf_jit_comp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -1077,7 +1077,7 @@ void bpf_int_jit_compile(struct bpf_prog + * may converge on the last pass. In such case do one more + * pass to emit the final image + */ +- for (pass = 0; pass < 10 || image; pass++) { ++ for (pass = 0; pass < 20 || image; pass++) { + proglen = do_jit(prog, addrs, image, oldproglen, &ctx); + if (proglen <= 0) { + image = NULL; +@@ -1100,6 +1100,7 @@ void bpf_int_jit_compile(struct bpf_prog + goto out; + } + oldproglen = proglen; ++ cond_resched(); + } + + if (bpf_jit_enable > 1) diff --git a/queue-4.4/kbuild-disable-clang-s-default-use-of-fmerge-all-constants.patch b/queue-4.4/kbuild-disable-clang-s-default-use-of-fmerge-all-constants.patch new file mode 100644 index 00000000000..e9c4a32a52e --- /dev/null +++ b/queue-4.4/kbuild-disable-clang-s-default-use-of-fmerge-all-constants.patch @@ -0,0 +1,132 @@ +From 87e0d4f0f37fb0c8c4aeeac46fff5e957738df79 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 21 Mar 2018 01:18:24 +0100 +Subject: kbuild: disable clang's default use of -fmerge-all-constants + +From: Daniel Borkmann + +commit 87e0d4f0f37fb0c8c4aeeac46fff5e957738df79 upstream. + +Prasad reported that he has seen crashes in BPF subsystem with netd +on Android with arm64 in the form of (note, the taint is unrelated): + + [ 4134.721483] Unable to handle kernel paging request at virtual address 800000001 + [ 4134.820925] Mem abort info: + [ 4134.901283] Exception class = DABT (current EL), IL = 32 bits + [ 4135.016736] SET = 0, FnV = 0 + [ 4135.119820] EA = 0, S1PTW = 0 + [ 4135.201431] Data abort info: + [ 4135.301388] ISV = 0, ISS = 0x00000021 + [ 4135.359599] CM = 0, WnR = 0 + [ 4135.470873] user pgtable: 4k pages, 39-bit VAs, pgd = ffffffe39b946000 + [ 4135.499757] [0000000800000001] *pgd=0000000000000000, *pud=0000000000000000 + [ 4135.660725] Internal error: Oops: 96000021 [#1] PREEMPT SMP + [ 4135.674610] Modules linked in: + [ 4135.682883] CPU: 5 PID: 1260 Comm: netd Tainted: G S W 4.14.19+ #1 + [ 4135.716188] task: ffffffe39f4aa380 task.stack: ffffff801d4e0000 + [ 4135.731599] PC is at bpf_prog_add+0x20/0x68 + [ 4135.741746] LR is at bpf_prog_inc+0x20/0x2c + [ 4135.751788] pc : [] lr : [] pstate: 60400145 + [ 4135.769062] sp : ffffff801d4e3ce0 + [...] + [ 4136.258315] Process netd (pid: 1260, stack limit = 0xffffff801d4e0000) + [ 4136.273746] Call trace: + [...] + [ 4136.442494] 3ca0: ffffff94ab7ad584 0000000060400145 ffffffe3a01bf8f8 0000000000000006 + [ 4136.460936] 3cc0: 0000008000000000 ffffff94ab844204 ffffff801d4e3cf0 ffffff94ab7ad584 + [ 4136.479241] [] bpf_prog_add+0x20/0x68 + [ 4136.491767] [] bpf_prog_inc+0x20/0x2c + [ 4136.504536] [] bpf_obj_get_user+0x204/0x22c + [ 4136.518746] [] SyS_bpf+0x5a8/0x1a88 + +Android's netd was basically pinning the uid cookie BPF map in BPF +fs (/sys/fs/bpf/traffic_cookie_uid_map) and later on retrieving it +again resulting in above panic. Issue is that the map was wrongly +identified as a prog! Above kernel was compiled with clang 4.0, +and it turns out that clang decided to merge the bpf_prog_iops and +bpf_map_iops into a single memory location, such that the two i_ops +could then not be distinguished anymore. + +Reason for this miscompilation is that clang has the more aggressive +-fmerge-all-constants enabled by default. In fact, clang source code +has a comment about it in lib/AST/ExprConstant.cpp on why it is okay +to do so: + + Pointers with different bases cannot represent the same object. + (Note that clang defaults to -fmerge-all-constants, which can + lead to inconsistent results for comparisons involving the address + of a constant; this generally doesn't matter in practice.) + +The issue never appeared with gcc however, since gcc does not enable +-fmerge-all-constants by default and even *explicitly* states in +it's option description that using this flag results in non-conforming +behavior, quote from man gcc: + + Languages like C or C++ require each variable, including multiple + instances of the same variable in recursive calls, to have distinct + locations, so using this option results in non-conforming behavior. + +There are also various clang bug reports open on that matter [1], +where clang developers acknowledge the non-conforming behavior, +and refer to disabling it with -fno-merge-all-constants. But even +if this gets fixed in clang today, there are already users out there +that triggered this. Thus, fix this issue by explicitly adding +-fno-merge-all-constants to the kernel's Makefile to generically +disable this optimization, since potentially other places in the +kernel could subtly break as well. + +Note, there is also a flag called -fmerge-constants (not supported +by clang), which is more conservative and only applies to strings +and it's enabled in gcc's -O/-O2/-O3/-Os optimization levels. In +gcc's code, the two flags -fmerge-{all-,}constants share the same +variable internally, so when disabling it via -fno-merge-all-constants, +then we really don't merge any const data (e.g. strings), and text +size increases with gcc (14,927,214 -> 14,942,646 for vmlinux.o). + + $ gcc -fverbose-asm -O2 foo.c -S -o foo.S + -> foo.S lists -fmerge-constants under options enabled + $ gcc -fverbose-asm -O2 -fno-merge-all-constants foo.c -S -o foo.S + -> foo.S doesn't list -fmerge-constants under options enabled + $ gcc -fverbose-asm -O2 -fno-merge-all-constants -fmerge-constants foo.c -S -o foo.S + -> foo.S lists -fmerge-constants under options enabled + +Thus, as a workaround we need to set both -fno-merge-all-constants +*and* -fmerge-constants in the Makefile in order for text size to +stay as is. + + [1] https://bugs.llvm.org/show_bug.cgi?id=18538 + +Reported-by: Prasad Sodagudi +Signed-off-by: Daniel Borkmann +Cc: Linus Torvalds +Cc: Chenbo Feng +Cc: Richard Smith +Cc: Chandler Carruth +Cc: linux-kernel@vger.kernel.org +Tested-by: Prasad Sodagudi +Acked-by: Alexei Starovoitov +Signed-off-by: Alexei Starovoitov +Signed-off-by: Greg Kroah-Hartman + +--- + Makefile | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/Makefile ++++ b/Makefile +@@ -784,6 +784,15 @@ KBUILD_CFLAGS += $(call cc-disable-warni + # disable invalid "can't wrap" optimizations for signed / pointers + KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow) + ++# clang sets -fmerge-all-constants by default as optimization, but this ++# is non-conforming behavior for C and in fact breaks the kernel, so we ++# need to disable it here generally. ++KBUILD_CFLAGS += $(call cc-option,-fno-merge-all-constants) ++ ++# for gcc -fno-merge-all-constants disables everything, but it is fine ++# to have actual conforming behavior enabled. ++KBUILD_CFLAGS += $(call cc-option,-fmerge-constants) ++ + # Make sure -fstack-check isn't enabled (like gentoo apparently did) + KBUILD_CFLAGS += $(call cc-option,-fno-stack-check,) + diff --git a/queue-4.4/series b/queue-4.4/series index e7501efa0b5..ed9e46b1009 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -38,3 +38,6 @@ x86-boot-64-verify-alignment-of-the-load-segment.patch x86-entry-64-don-t-use-ist-entry-for-bp-stack.patch perf-x86-intel-don-t-accidentally-clear-high-bits-in-bdw_limit_period.patch staging-lustre-ptlrpc-kfree-used-instead-of-kvfree.patch +kbuild-disable-clang-s-default-use-of-fmerge-all-constants.patch +bpf-skip-unnecessary-capability-check.patch +bpf-x64-increase-number-of-passes.patch