aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2019-03-04 15:08:53 -0500
committerAlexei Starovoitov <ast@kernel.org>2019-03-07 11:47:13 -0500
commit20182390c4134478d795a096ddb8dddcc648e28a (patch)
tree912da4b5a7ce4279311206bc1e8ede8619d057b3
parente8e3437762ad938880dd48a3c52d702e7cf3c124 (diff)
bpf: fix replace_map_fd_with_map_ptr's ldimm64 second imm field
Non-zero imm value in the second part of the ldimm64 instruction for BPF_PSEUDO_MAP_FD is invalid, and thus must be rejected. The map fd only ever sits in the first instructions' imm field. None of the BPF loaders known to us are using it, so risk of regression is minimal. For clarity and consistency, the few insn->{src_reg,imm} occurrences are rewritten into insn[0].{src_reg,imm}. Add a test case to the BPF selftest suite as well. Fixes: 0246e64d9a5f ("bpf: handle pseudo BPF_LD_IMM64 insn") Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Song Liu <songliubraving@fb.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
-rw-r--r--kernel/bpf/verifier.c10
-rw-r--r--tools/testing/selftests/bpf/verifier/ld_imm64.c15
2 files changed, 19 insertions, 6 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index a7b96bf0e654..ce166a002d16 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -6678,17 +6678,17 @@ static int replace_map_fd_with_map_ptr(struct bpf_verifier_env *env)
6678 /* valid generic load 64-bit imm */ 6678 /* valid generic load 64-bit imm */
6679 goto next_insn; 6679 goto next_insn;
6680 6680
6681 if (insn->src_reg != BPF_PSEUDO_MAP_FD) { 6681 if (insn[0].src_reg != BPF_PSEUDO_MAP_FD ||
6682 verbose(env, 6682 insn[1].imm != 0) {
6683 "unrecognized bpf_ld_imm64 insn\n"); 6683 verbose(env, "unrecognized bpf_ld_imm64 insn\n");
6684 return -EINVAL; 6684 return -EINVAL;
6685 } 6685 }
6686 6686
6687 f = fdget(insn->imm); 6687 f = fdget(insn[0].imm);
6688 map = __bpf_map_get(f); 6688 map = __bpf_map_get(f);
6689 if (IS_ERR(map)) { 6689 if (IS_ERR(map)) {
6690 verbose(env, "fd %d is not pointing to valid bpf_map\n", 6690 verbose(env, "fd %d is not pointing to valid bpf_map\n",
6691 insn->imm); 6691 insn[0].imm);
6692 return PTR_ERR(map); 6692 return PTR_ERR(map);
6693 } 6693 }
6694 6694
diff --git a/tools/testing/selftests/bpf/verifier/ld_imm64.c b/tools/testing/selftests/bpf/verifier/ld_imm64.c
index 28b8c805a293..3856dba733e9 100644
--- a/tools/testing/selftests/bpf/verifier/ld_imm64.c
+++ b/tools/testing/selftests/bpf/verifier/ld_imm64.c
@@ -122,7 +122,7 @@
122 .insns = { 122 .insns = {
123 BPF_MOV64_IMM(BPF_REG_1, 0), 123 BPF_MOV64_IMM(BPF_REG_1, 0),
124 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1), 124 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, 0, BPF_REG_1, 0, 1),
125 BPF_RAW_INSN(0, 0, 0, 0, 1), 125 BPF_RAW_INSN(0, 0, 0, 0, 0),
126 BPF_EXIT_INSN(), 126 BPF_EXIT_INSN(),
127 }, 127 },
128 .errstr = "not pointing to valid bpf_map", 128 .errstr = "not pointing to valid bpf_map",
@@ -139,3 +139,16 @@
139 .errstr = "invalid bpf_ld_imm64 insn", 139 .errstr = "invalid bpf_ld_imm64 insn",
140 .result = REJECT, 140 .result = REJECT,
141}, 141},
142{
143 "test14 ld_imm64: reject 2nd imm != 0",
144 .insns = {
145 BPF_MOV64_IMM(BPF_REG_0, 0),
146 BPF_RAW_INSN(BPF_LD | BPF_IMM | BPF_DW, BPF_REG_1,
147 BPF_PSEUDO_MAP_FD, 0, 0),
148 BPF_RAW_INSN(0, 0, 0, 0, 0xfefefe),
149 BPF_EXIT_INSN(),
150 },
151 .fixup_map_hash_48b = { 1 },
152 .errstr = "unrecognized bpf_ld_imm64 insn",
153 .result = REJECT,
154},