Unverified Commit 16dfd8c8 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!11845 bpf: verifier: prevent userspace memory access

parents 0d2e536b b7aa4343
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -2968,3 +2968,9 @@ void bpf_arch_poke_desc_update(struct bpf_jit_poke_descriptor *poke,
		BUG_ON(ret < 0);
	}
}

/* x86-64 JIT emits its own code to filter user addresses so return 0 here */
u64 bpf_arch_uaddress_limit(void)
{
	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -916,6 +916,7 @@ bool bpf_jit_needs_zext(void);
bool bpf_jit_supports_subprog_tailcalls(void);
bool bpf_jit_supports_kfunc_call(void);
bool bpf_jit_supports_far_kfunc_call(void);
u64 bpf_arch_uaddress_limit(void);
bool bpf_helper_changes_pkt_data(void *func);

static inline bool bpf_dump_raw_ok(const struct cred *cred)
+9 −0
Original line number Diff line number Diff line
@@ -2906,6 +2906,15 @@ bool __weak bpf_jit_supports_far_kfunc_call(void)
	return false;
}

u64 __weak bpf_arch_uaddress_limit(void)
{
#if defined(CONFIG_64BIT) && defined(CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE)
	return TASK_SIZE;
#else
	return 0;
#endif
}

/* To execute LD_ABS/LD_IND instructions __bpf_prog_run() may call
 * skb_copy_bits(), so provide a weak definition of it for NET-less config.
 */
+30 −0
Original line number Diff line number Diff line
@@ -18942,6 +18942,36 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
			continue;
		}
		/* Make it impossible to de-reference a userspace address */
		if (BPF_CLASS(insn->code) == BPF_LDX &&
		    (BPF_MODE(insn->code) == BPF_PROBE_MEM ||
		     BPF_MODE(insn->code) == BPF_PROBE_MEMSX)) {
			struct bpf_insn *patch = &insn_buf[0];
			u64 uaddress_limit = bpf_arch_uaddress_limit();
			if (!uaddress_limit)
				continue;
			*patch++ = BPF_MOV64_REG(BPF_REG_AX, insn->src_reg);
			if (insn->off)
				*patch++ = BPF_ALU64_IMM(BPF_ADD, BPF_REG_AX, insn->off);
			*patch++ = BPF_ALU64_IMM(BPF_RSH, BPF_REG_AX, 32);
			*patch++ = BPF_JMP_IMM(BPF_JLE, BPF_REG_AX, uaddress_limit >> 32, 2);
			*patch++ = *insn;
			*patch++ = BPF_JMP_IMM(BPF_JA, 0, 0, 1);
			*patch++ = BPF_MOV64_IMM(insn->dst_reg, 0);
			cnt = patch - insn_buf;
			new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, cnt);
			if (!new_prog)
				return -ENOMEM;
			delta    += cnt - 1;
			env->prog = prog = new_prog;
			insn      = new_prog->insnsi + i + delta;
			continue;
		}
		/* Implement LD_ABS and LD_IND with a rewrite, if supported by the program type. */
		if (BPF_CLASS(insn->code) == BPF_LD &&
		    (BPF_MODE(insn->code) == BPF_ABS ||