aboutsummaryrefslogtreecommitdiffstats
path: root/common/recipes-kernel/linux/linux-yocto-4.9.21/0042-bpf-adjust-insn_aux_data-when-patching-insns.patch
diff options
context:
space:
mode:
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0042-bpf-adjust-insn_aux_data-when-patching-insns.patch')
-rw-r--r--common/recipes-kernel/linux/linux-yocto-4.9.21/0042-bpf-adjust-insn_aux_data-when-patching-insns.patch103
1 files changed, 103 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0042-bpf-adjust-insn_aux_data-when-patching-insns.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0042-bpf-adjust-insn_aux_data-when-patching-insns.patch
new file mode 100644
index 00000000..f6ce7d86
--- /dev/null
+++ b/common/recipes-kernel/linux/linux-yocto-4.9.21/0042-bpf-adjust-insn_aux_data-when-patching-insns.patch
@@ -0,0 +1,103 @@
+From cf7ad5027cb0764ea5276a432a9a3a402d2a2034 Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <daniel@iogearbox.net>
+Date: Fri, 22 Dec 2017 16:29:02 +0100
+Subject: [PATCH 042/103] bpf: adjust insn_aux_data when patching insns
+
+From: Alexei Starovoitov <ast@fb.com>
+
+[ Upstream commit 8041902dae5299c1f194ba42d14383f734631009 ]
+
+convert_ctx_accesses() replaces single bpf instruction with a set of
+instructions. Adjust corresponding insn_aux_data while patching.
+It's needed to make sure subsequent 'for(all insn)' loops
+have matching insn and insn_aux_data.
+
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Acked-by: Daniel Borkmann <daniel@iogearbox.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/bpf/verifier.c | 44 +++++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 39 insertions(+), 5 deletions(-)
+
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 85d1c94..66ee0c4 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -3017,6 +3017,41 @@ static void convert_pseudo_ld_imm64(struct bpf_verifier_env *env)
+ insn->src_reg = 0;
+ }
+
++/* single env->prog->insni[off] instruction was replaced with the range
++ * insni[off, off + cnt). Adjust corresponding insn_aux_data by copying
++ * [0, off) and [off, end) to new locations, so the patched range stays zero
++ */
++static int adjust_insn_aux_data(struct bpf_verifier_env *env, u32 prog_len,
++ u32 off, u32 cnt)
++{
++ struct bpf_insn_aux_data *new_data, *old_data = env->insn_aux_data;
++
++ if (cnt == 1)
++ return 0;
++ new_data = vzalloc(sizeof(struct bpf_insn_aux_data) * prog_len);
++ if (!new_data)
++ return -ENOMEM;
++ memcpy(new_data, old_data, sizeof(struct bpf_insn_aux_data) * off);
++ memcpy(new_data + off + cnt - 1, old_data + off,
++ sizeof(struct bpf_insn_aux_data) * (prog_len - off - cnt + 1));
++ env->insn_aux_data = new_data;
++ vfree(old_data);
++ return 0;
++}
++
++static struct bpf_prog *bpf_patch_insn_data(struct bpf_verifier_env *env, u32 off,
++ const struct bpf_insn *patch, u32 len)
++{
++ struct bpf_prog *new_prog;
++
++ new_prog = bpf_patch_insn_single(env->prog, off, patch, len);
++ if (!new_prog)
++ return NULL;
++ if (adjust_insn_aux_data(env, new_prog->len, off, len))
++ return NULL;
++ return new_prog;
++}
++
+ /* convert load instructions that access fields of 'struct __sk_buff'
+ * into sequence of instructions that access fields of 'struct sk_buff'
+ */
+@@ -3036,10 +3071,10 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
+ verbose("bpf verifier is misconfigured\n");
+ return -EINVAL;
+ } else if (cnt) {
+- new_prog = bpf_patch_insn_single(env->prog, 0,
+- insn_buf, cnt);
++ new_prog = bpf_patch_insn_data(env, 0, insn_buf, cnt);
+ if (!new_prog)
+ return -ENOMEM;
++
+ env->prog = new_prog;
+ delta += cnt - 1;
+ }
+@@ -3060,7 +3095,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
+ else
+ continue;
+
+- if (env->insn_aux_data[i].ptr_type != PTR_TO_CTX)
++ if (env->insn_aux_data[i + delta].ptr_type != PTR_TO_CTX)
+ continue;
+
+ cnt = ops->convert_ctx_access(type, insn->dst_reg, insn->src_reg,
+@@ -3070,8 +3105,7 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env)
+ return -EINVAL;
+ }
+
+- new_prog = bpf_patch_insn_single(env->prog, i + delta, insn_buf,
+- cnt);
++ new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);
+ if (!new_prog)
+ return -ENOMEM;
+
+--
+2.7.4
+