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

!9731 v2 Backport bpf bugfixes

Merge Pull Request from: @ci-robot 
 
PR sync from: Zheng Yejian <zhengyejian1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/AGE6M36INRECJD325SMJBMVWLIZAGK54/ 
v1 -> v2:
  Update bugzilla link info in patch1 & patch2

Daniel Borkmann (1):
  bpf: Fix __reg_bound_offset 64->32 var_off subreg propagation

Krister Johansen (1):
  bpf: ensure main program has an extable

Kumar Kartikeya Dwivedi (1):
  bpf: Clobber stack slot when writing over spilled PTR_TO_BTF_ID

Stanislav Fomichev (1):
  bpf: Don't EFAULT for {g,s}setsockopt with wrong optlen

Wang Yufen (1):
  bpf: Fix memory leaks in __check_func_call


-- 
2.25.1
 
https://gitee.com/openeuler/kernel/issues/IAAAW9 
 
Link:https://gitee.com/openeuler/kernel/pulls/9731

 

Reviewed-by: default avatarYe Weihua <yeweihua4@huawei.com>
Signed-off-by: default avatarJialin Zhang <zhangjialin11@huawei.com>
parents 3f2841fc 4f962401
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -1477,6 +1477,12 @@ int __cgroup_bpf_run_filter_setsockopt(struct sock *sk, int *level,
		ret = 1;
	} else if (ctx.optlen > max_optlen || ctx.optlen < -1) {
		/* optlen is out of bounds */
		if (*optlen > PAGE_SIZE && ctx.optlen >= 0) {
			pr_info_once("bpf setsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n",
				     ctx.optlen, max_optlen);
			ret = 0;
			goto out;
		}
		ret = -EFAULT;
	} else {
		/* optlen within bounds, run kernel handler */
@@ -1532,6 +1538,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
		.optname = optname,
		.retval = retval,
	};
	int orig_optlen;
	int ret;

	/* Opportunistic check to see whether we have any BPF program
@@ -1541,6 +1548,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
	if (__cgroup_bpf_prog_array_is_empty(cgrp, CGROUP_GETSOCKOPT))
		return retval;

	orig_optlen = max_optlen;
	ctx.optlen = max_optlen;

	max_optlen = sockopt_alloc_buf(&ctx, max_optlen, &buf);
@@ -1564,6 +1572,7 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
			ret = -EFAULT;
			goto out;
		}
		orig_optlen = ctx.optlen;

		if (copy_from_user(ctx.optval, optval,
				   min(ctx.optlen, max_optlen)) != 0) {
@@ -1583,6 +1592,12 @@ int __cgroup_bpf_run_filter_getsockopt(struct sock *sk, int level,
	}

	if (optval && (ctx.optlen > max_optlen || ctx.optlen < 0)) {
		if (orig_optlen > PAGE_SIZE && ctx.optlen >= 0) {
			pr_info_once("bpf getsockopt: ignoring program buffer with optlen=%d (max_optlen=%d)\n",
				     ctx.optlen, max_optlen);
			ret = retval;
			goto out;
		}
		ret = -EFAULT;
		goto out;
	}
+20 −13
Original line number Diff line number Diff line
@@ -1281,7 +1281,7 @@ static void __reg_bound_offset(struct bpf_reg_state *reg)
	struct tnum var64_off = tnum_intersect(reg->var_off,
					       tnum_range(reg->umin_value,
							  reg->umax_value));
	struct tnum var32_off = tnum_intersect(tnum_subreg(reg->var_off),
	struct tnum var32_off = tnum_intersect(tnum_subreg(var64_off),
					       tnum_range(reg->u32_min_value,
							  reg->u32_max_value));

@@ -4333,10 +4333,6 @@ static int check_stack_range_initialized(
			goto mark;
		}

		if (is_spilled_reg(&state->stack[spi]) &&
		    state->stack[spi].spilled_ptr.type == PTR_TO_BTF_ID)
			goto mark;

		if (is_spilled_reg(&state->stack[spi]) &&
		    (state->stack[spi].spilled_ptr.type == SCALAR_VALUE ||
		     env->allow_ptr_leaks)) {
@@ -4366,6 +4362,11 @@ static int check_stack_range_initialized(
		mark_reg_read(env, &state->stack[spi].spilled_ptr,
			      state->stack[spi].spilled_ptr.parent,
			      REG_LIVE_READ64);
		/* We do not set REG_LIVE_WRITTEN for stack slot, as we can not
		 * be sure that whether stack slot is written to or not. Hence,
		 * we must still conservatively propagate reads upwards even if
		 * helper may write to the entire memory range.
		 */
	}
	return 0;
}
@@ -5430,7 +5431,7 @@ static int check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
	/* Transfer references to the callee */
	err = copy_reference_state(callee, caller);
	if (err)
		return err;
		goto err_out;

	/* copy r1 - r5 args that callee can access.  The copy includes parent
	 * pointers, which connects us up to the liveness chain
@@ -5453,6 +5454,10 @@ static int check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
		print_verifier_state(env, callee);
	}
	return 0;
err_out:
	free_func_state(callee);
	state->frame[state->curframe + 1] = NULL;
	return err;
}

static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
@@ -5475,8 +5480,7 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
		return -EINVAL;
	}

	state->curframe--;
	caller = state->frame[state->curframe];
	caller = state->frame[state->curframe - 1];
	/* return to the caller whatever r0 had in the callee */
	caller->regs[BPF_REG_0] = *r0;

@@ -5494,7 +5498,7 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
	}
	/* clear everything in the callee */
	free_func_state(callee);
	state->frame[state->curframe + 1] = NULL;
	state->frame[state->curframe--] = NULL;
	return 0;
}

@@ -11539,9 +11543,10 @@ static int jit_subprogs(struct bpf_verifier_env *env)
	}

	/* finally lock prog and jit images for all functions and
	 * populate kallsysm
	 * populate kallsysm. Begin at the first subprogram, since
	 * bpf_prog_load will add the kallsyms for the main program.
	 */
	for (i = 0; i < env->subprog_cnt; i++) {
	for (i = 1; i < env->subprog_cnt; i++) {
		bpf_prog_lock_ro(func[i]);
		bpf_prog_kallsyms_add(func[i]);
	}
@@ -11561,6 +11566,8 @@ static int jit_subprogs(struct bpf_verifier_env *env)

	prog->jited = 1;
	prog->bpf_func = func[0]->bpf_func;
	prog->aux->extable = func[0]->aux->extable;
	prog->aux->num_exentries = func[0]->aux->num_exentries;
	prog->aux->func = func;
	prog->aux->func_cnt = env->subprog_cnt;
	bpf_prog_free_unused_jited_linfo(prog);
+2 −2
Original line number Diff line number Diff line
@@ -575,14 +575,14 @@ static struct bpf_align_test tests[] = {
			/* New unknown value in R7 is (4n), >= 76 */
			{15, "R7_w=inv(id=0,umin_value=76,umax_value=1096,var_off=(0x0; 0x7fc))"},
			/* Adding it to packet pointer gives nice bounds again */
			{16, "R5_w=pkt(id=3,off=0,r=0,umin_value=2,umax_value=1082,var_off=(0x2; 0xfffffffc)"},
			{16, "R5_w=pkt(id=3,off=0,r=0,umin_value=2,umax_value=1082,var_off=(0x2; 0x7fc)"},
			/* At the time the word size load is performed from R5,
			 * its total fixed offset is NET_IP_ALIGN + reg->off (0)
			 * which is 2.  Then the variable offset is (4n+2), so
			 * the total offset is 4-byte aligned and meets the
			 * load's requirements.
			 */
			{20, "R5=pkt(id=3,off=0,r=4,umin_value=2,umax_value=1082,var_off=(0x2; 0xfffffffc)"},
			{20, "R5=pkt(id=3,off=0,r=4,umin_value=2,umax_value=1082,var_off=(0x2; 0x7fc)"},
		},
	},
};