Skip to content

Commit 49630dd

Browse files
borkmanngregkh
authored andcommitted
bpf: don't let ldimm64 leak map addresses on unprivileged
commit 0d0e57697f162da4aa218b5feafe614fb666db07 upstream. The patch fixes two things at once: 1) It checks the env->allow_ptr_leaks and only prints the map address to the log if we have the privileges to do so, otherwise it just dumps 0 as we would when kptr_restrict is enabled on %pK. Given the latter is off by default and not every distro sets it, I don't want to rely on this, hence the 0 by default for unprivileged. 2) Printing of ldimm64 in the verifier log is currently broken in that we don't print the full immediate, but only the 32 bit part of the first insn part for ldimm64. Thus, fix this up as well; it's okay to access, since we verified all ldimm64 earlier already (including just constants) through replace_map_fd_with_map_ptr(). Fixes: 1be7f75 ("bpf: enable non-root eBPF programs") Fixes: cbd3570 ("bpf: verifier (add ability to receive verification log)") Reported-by: Jann Horn <jannh@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net> [bwh: Backported to 4.4: s/bpf_verifier_env/verifier_env/] Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 07e3aff commit 49630dd

1 file changed

Lines changed: 16 additions & 5 deletions

File tree

kernel/bpf/verifier.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ static const char *const bpf_jmp_string[16] = {
313313
[BPF_EXIT >> 4] = "exit",
314314
};
315315

316-
static void print_bpf_insn(struct bpf_insn *insn)
316+
static void print_bpf_insn(const struct verifier_env *env,
317+
const struct bpf_insn *insn)
317318
{
318319
u8 class = BPF_CLASS(insn->code);
319320

@@ -377,9 +378,19 @@ static void print_bpf_insn(struct bpf_insn *insn)
377378
insn->code,
378379
bpf_ldst_string[BPF_SIZE(insn->code) >> 3],
379380
insn->src_reg, insn->imm);
380-
} else if (BPF_MODE(insn->code) == BPF_IMM) {
381-
verbose("(%02x) r%d = 0x%x\n",
382-
insn->code, insn->dst_reg, insn->imm);
381+
} else if (BPF_MODE(insn->code) == BPF_IMM &&
382+
BPF_SIZE(insn->code) == BPF_DW) {
383+
/* At this point, we already made sure that the second
384+
* part of the ldimm64 insn is accessible.
385+
*/
386+
u64 imm = ((u64)(insn + 1)->imm << 32) | (u32)insn->imm;
387+
bool map_ptr = insn->src_reg == BPF_PSEUDO_MAP_FD;
388+
389+
if (map_ptr && !env->allow_ptr_leaks)
390+
imm = 0;
391+
392+
verbose("(%02x) r%d = 0x%llx\n", insn->code,
393+
insn->dst_reg, (unsigned long long)imm);
383394
} else {
384395
verbose("BUG_ld_%02x\n", insn->code);
385396
return;
@@ -1764,7 +1775,7 @@ static int do_check(struct verifier_env *env)
17641775

17651776
if (log_level) {
17661777
verbose("%d: ", insn_idx);
1767-
print_bpf_insn(insn);
1778+
print_bpf_insn(env, insn);
17681779
}
17691780

17701781
if (class == BPF_ALU || class == BPF_ALU64) {

0 commit comments

Comments
 (0)