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

!13993 50164

Merge Pull Request from: @ci-robot 
 
PR sync from: Xiaomeng Zhang <zhangxiaomeng13@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/IGVFHU7PRMQ7WDAQ6GLC7GC6W4M75WSR/ 
*** BLURB HERE ***

Daniel Borkmann (3):
  bpf: Add MEM_WRITE attribute
  bpf: Fix overloading of MEM_UNINIT's meaning
  bpf: Remove MEM_UNINIT from skb/xdp MTU helpers

Xiaomeng Zhang (1):
  bpf: Fix kabi breakage in enum bpf_type_flag and bpf_arg_type


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/IB2SUA 
 
Link:https://gitee.com/openeuler/kernel/pulls/13993

 

Reviewed-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
Reviewed-by: default avatarXu Kuohai <xukuohai@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents b3dd80fc ce34e4b0
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -625,6 +625,7 @@ enum bpf_type_flag {
	 */
	PTR_UNTRUSTED		= BIT(6 + BPF_BASE_TYPE_BITS),

	/* MEM can be uninitialized. */
	MEM_UNINIT		= BIT(7 + BPF_BASE_TYPE_BITS),

	/* DYNPTR points to memory local to the bpf program. */
@@ -691,6 +692,15 @@ enum bpf_type_flag {
	/* Fix kabi by inserting broken enum as bpf_type_flag is used only in kernel */
	KABI_BROKEN_INSERT_ENUM(MEM_ALIGNED = BIT(17 + BPF_BASE_TYPE_BITS))

	/* MEM is being written to, often combined with MEM_UNINIT. Non-presence
	 * of MEM_WRITE means that MEM is only being read. MEM_WRITE without the
	 * MEM_UNINIT means that memory needs to be initialized since it is also
	 * read.
	 */

	/* Fix kabi by inserting broken enum as bpf_type_flag is used only in kernel */
	KABI_BROKEN_INSERT_ENUM(MEM_WRITE = BIT(18 + BPF_BASE_TYPE_BITS))

	__BPF_TYPE_FLAG_MAX,
	__BPF_TYPE_LAST_FLAG	= __BPF_TYPE_FLAG_MAX - 1,
};
@@ -751,10 +761,12 @@ enum bpf_arg_type {
	ARG_PTR_TO_SOCKET_OR_NULL	= PTR_MAYBE_NULL | ARG_PTR_TO_SOCKET,
	ARG_PTR_TO_STACK_OR_NULL	= PTR_MAYBE_NULL | ARG_PTR_TO_STACK,
	ARG_PTR_TO_BTF_ID_OR_NULL	= PTR_MAYBE_NULL | ARG_PTR_TO_BTF_ID,
	/* pointer to memory does not need to be initialized, helper function must fill
	 * all bytes or clear them in error case.
	/* Pointer to memory does not need to be initialized, since helper function
	 * fills all bytes or clears them in error case.
	 */
	ARG_PTR_TO_UNINIT_MEM		= MEM_UNINIT | ARG_PTR_TO_MEM,
	/* Fix kabi by removing and inserting enum as bpf_arg_type is used only in kernel */
	KABI_BROKEN_REMOVE_ENUM(ARG_PTR_TO_UNINIT_MEM = MEM_UNINIT | ARG_PTR_TO_MEM)
	KABI_BROKEN_INSERT_ENUM(ARG_PTR_TO_UNINIT_MEM = MEM_UNINIT | MEM_WRITE | ARG_PTR_TO_MEM)
	/* Pointer to valid memory of size known at compile time. */
	ARG_PTR_TO_FIXED_SIZE_MEM	= MEM_FIXED_SIZE | ARG_PTR_TO_MEM,

+5 −5
Original line number Diff line number Diff line
@@ -110,7 +110,7 @@ const struct bpf_func_proto bpf_map_pop_elem_proto = {
	.gpl_only	= false,
	.ret_type	= RET_INTEGER,
	.arg1_type	= ARG_CONST_MAP_PTR,
	.arg2_type	= ARG_PTR_TO_MAP_VALUE | MEM_UNINIT,
	.arg2_type	= ARG_PTR_TO_MAP_VALUE | MEM_UNINIT | MEM_WRITE,
};

BPF_CALL_2(bpf_map_peek_elem, struct bpf_map *, map, void *, value)
@@ -123,7 +123,7 @@ const struct bpf_func_proto bpf_map_peek_elem_proto = {
	.gpl_only	= false,
	.ret_type	= RET_INTEGER,
	.arg1_type	= ARG_CONST_MAP_PTR,
	.arg2_type	= ARG_PTR_TO_MAP_VALUE | MEM_UNINIT,
	.arg2_type	= ARG_PTR_TO_MAP_VALUE | MEM_UNINIT | MEM_WRITE,
};

BPF_CALL_3(bpf_map_lookup_percpu_elem, struct bpf_map *, map, void *, key, u32, cpu)
@@ -538,7 +538,7 @@ const struct bpf_func_proto bpf_strtol_proto = {
	.arg1_type	= ARG_PTR_TO_MEM | MEM_RDONLY,
	.arg2_type	= ARG_CONST_SIZE,
	.arg3_type	= ARG_ANYTHING,
	.arg4_type	= ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED,
	.arg4_type	= ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_WRITE | MEM_ALIGNED,
	.arg4_size	= sizeof(s64),
};

@@ -568,7 +568,7 @@ const struct bpf_func_proto bpf_strtoul_proto = {
	.arg1_type	= ARG_PTR_TO_MEM | MEM_RDONLY,
	.arg2_type	= ARG_CONST_SIZE,
	.arg3_type	= ARG_ANYTHING,
	.arg4_type	= ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED,
	.arg4_type	= ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_WRITE | MEM_ALIGNED,
	.arg4_size	= sizeof(u64),
};

@@ -1655,7 +1655,7 @@ static const struct bpf_func_proto bpf_dynptr_from_mem_proto = {
	.arg1_type	= ARG_PTR_TO_UNINIT_MEM,
	.arg2_type	= ARG_CONST_SIZE_OR_ZERO,
	.arg3_type	= ARG_ANYTHING,
	.arg4_type	= ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_LOCAL | MEM_UNINIT,
	.arg4_type	= ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_LOCAL | MEM_UNINIT | MEM_WRITE,
};

BPF_CALL_5(bpf_dynptr_read, void *, dst, u32, len, const struct bpf_dynptr_kern *, src,
+1 −1
Original line number Diff line number Diff line
@@ -632,7 +632,7 @@ const struct bpf_func_proto bpf_ringbuf_reserve_dynptr_proto = {
	.arg1_type	= ARG_CONST_MAP_PTR,
	.arg2_type	= ARG_ANYTHING,
	.arg3_type	= ARG_ANYTHING,
	.arg4_type	= ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_RINGBUF | MEM_UNINIT,
	.arg4_type	= ARG_PTR_TO_DYNPTR | DYNPTR_TYPE_RINGBUF | MEM_UNINIT | MEM_WRITE,
};

BPF_CALL_2(bpf_ringbuf_submit_dynptr, struct bpf_dynptr_kern *, ptr, u64, flags)
+1 −1
Original line number Diff line number Diff line
@@ -5713,7 +5713,7 @@ static const struct bpf_func_proto bpf_kallsyms_lookup_name_proto = {
	.arg1_type	= ARG_PTR_TO_MEM,
	.arg2_type	= ARG_CONST_SIZE_OR_ZERO,
	.arg3_type	= ARG_ANYTHING,
	.arg4_type	= ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_ALIGNED,
	.arg4_type	= ARG_PTR_TO_FIXED_SIZE_MEM | MEM_UNINIT | MEM_WRITE | MEM_ALIGNED,
	.arg4_size	= sizeof(u64),
};

+35 −38
Original line number Diff line number Diff line
@@ -7276,7 +7276,8 @@ static int check_stack_range_initialized(
}
static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
				   int access_size, bool zero_size_allowed,
				   int access_size, enum bpf_access_type access_type,
				   bool zero_size_allowed,
				   struct bpf_call_arg_meta *meta)
{
	struct bpf_reg_state *regs = cur_regs(env), *reg = &regs[regno];
@@ -7288,7 +7289,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
		return check_packet_access(env, regno, reg->off, access_size,
					   zero_size_allowed);
	case PTR_TO_MAP_KEY:
		if (meta && meta->raw_mode) {
		if (access_type == BPF_WRITE) {
			verbose(env, "R%d cannot write into %s\n", regno,
				reg_type_str(env, reg->type));
			return -EACCES;
@@ -7296,15 +7297,13 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
		return check_mem_region_access(env, regno, reg->off, access_size,
					       reg->map_ptr->key_size, false);
	case PTR_TO_MAP_VALUE:
		if (check_map_access_type(env, regno, reg->off, access_size,
					  meta && meta->raw_mode ? BPF_WRITE :
					  BPF_READ))
		if (check_map_access_type(env, regno, reg->off, access_size, access_type))
			return -EACCES;
		return check_map_access(env, regno, reg->off, access_size,
					zero_size_allowed, ACCESS_HELPER);
	case PTR_TO_MEM:
		if (type_is_rdonly_mem(reg->type)) {
			if (meta && meta->raw_mode) {
			if (access_type == BPF_WRITE) {
				verbose(env, "R%d cannot write into %s\n", regno,
					reg_type_str(env, reg->type));
				return -EACCES;
@@ -7315,7 +7314,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
					       zero_size_allowed);
	case PTR_TO_BUF:
		if (type_is_rdonly_mem(reg->type)) {
			if (meta && meta->raw_mode) {
			if (access_type == BPF_WRITE) {
				verbose(env, "R%d cannot write into %s\n", regno,
					reg_type_str(env, reg->type));
				return -EACCES;
@@ -7343,7 +7342,6 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
		 * Dynamically check it now.
		 */
		if (!env->ops->convert_ctx_access) {
			enum bpf_access_type atype = meta && meta->raw_mode ? BPF_WRITE : BPF_READ;
			int offset = access_size - 1;
			/* Allow zero-byte read from PTR_TO_CTX */
@@ -7351,7 +7349,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
				return zero_size_allowed ? 0 : -EACCES;
			return check_mem_access(env, env->insn_idx, regno, offset, BPF_B,
						atype, -1, false, false);
						access_type, -1, false, false);
		}
		fallthrough;
@@ -7370,6 +7368,7 @@ static int check_helper_mem_access(struct bpf_verifier_env *env, int regno,
static int check_mem_size_reg(struct bpf_verifier_env *env,
			      struct bpf_reg_state *reg, u32 regno,
			      enum bpf_access_type access_type,
			      bool zero_size_allowed,
			      struct bpf_call_arg_meta *meta)
{
@@ -7385,15 +7384,12 @@ static int check_mem_size_reg(struct bpf_verifier_env *env,
	 */
	meta->msize_max_value = reg->umax_value;
	/* The register is SCALAR_VALUE; the access check
	 * happens using its boundaries.
	/* The register is SCALAR_VALUE; the access check happens using
	 * its boundaries. For unprivileged variable accesses, disable
	 * raw mode so that the program is required to initialize all
	 * the memory that the helper could just partially fill up.
	 */
	if (!tnum_is_const(reg->var_off))
		/* For unprivileged variable accesses, disable raw
		 * mode so that the program is required to
		 * initialize all the memory that the helper could
		 * just partially fill up.
		 */
		meta = NULL;
	if (reg->smin_value < 0) {
@@ -7413,9 +7409,8 @@ static int check_mem_size_reg(struct bpf_verifier_env *env,
			regno);
		return -EACCES;
	}
	err = check_helper_mem_access(env, regno - 1,
				      reg->umax_value,
				      zero_size_allowed, meta);
	err = check_helper_mem_access(env, regno - 1, reg->umax_value,
				      access_type, zero_size_allowed, meta);
	if (!err)
		err = mark_chain_precision(env, regno);
	return err;
@@ -7426,13 +7421,11 @@ int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg,
{
	bool may_be_null = type_may_be_null(reg->type);
	struct bpf_reg_state saved_reg;
	struct bpf_call_arg_meta meta;
	int err;
	if (register_is_null(reg))
		return 0;
	memset(&meta, 0, sizeof(meta));
	/* Assuming that the register contains a value check if the memory
	 * access is safe. Temporarily save and restore the register's state as
	 * the conversion shouldn't be visible to a caller.
@@ -7442,10 +7435,8 @@ int check_mem_reg(struct bpf_verifier_env *env, struct bpf_reg_state *reg,
		mark_ptr_not_null_reg(reg);
	}
	err = check_helper_mem_access(env, regno, mem_size, true, &meta);
	/* Check access for BPF_WRITE */
	meta.raw_mode = true;
	err = err ?: check_helper_mem_access(env, regno, mem_size, true, &meta);
	err = check_helper_mem_access(env, regno, mem_size, BPF_READ, true, NULL);
	err = err ?: check_helper_mem_access(env, regno, mem_size, BPF_WRITE, true, NULL);
	if (may_be_null)
		*reg = saved_reg;
@@ -7471,13 +7462,12 @@ static int check_kfunc_mem_size_reg(struct bpf_verifier_env *env, struct bpf_reg
		mark_ptr_not_null_reg(mem_reg);
	}
	err = check_mem_size_reg(env, reg, regno, true, &meta);
	/* Check access for BPF_WRITE */
	meta.raw_mode = true;
	err = err ?: check_mem_size_reg(env, reg, regno, true, &meta);
	err = check_mem_size_reg(env, reg, regno, BPF_READ, true, &meta);
	err = err ?: check_mem_size_reg(env, reg, regno, BPF_WRITE, true, &meta);
	if (may_be_null)
		*mem_reg = saved_reg;
	return err;
}
@@ -8657,9 +8647,8 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
			verbose(env, "invalid map_ptr to access map->key\n");
			return -EACCES;
		}
		err = check_helper_mem_access(env, regno,
					      meta->map_ptr->key_size, false,
					      NULL);
		err = check_helper_mem_access(env, regno, meta->map_ptr->key_size,
					      BPF_READ, false, NULL);
		break;
	case ARG_PTR_TO_MAP_VALUE:
		if (type_may_be_null(arg_type) && register_is_null(reg))
@@ -8674,9 +8663,9 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
			return -EACCES;
		}
		meta->raw_mode = arg_type & MEM_UNINIT;
		err = check_helper_mem_access(env, regno,
					      meta->map_ptr->value_size, false,
					      meta);
		err = check_helper_mem_access(env, regno, meta->map_ptr->value_size,
					      arg_type & MEM_WRITE ? BPF_WRITE : BPF_READ,
					      false, meta);
		break;
	case ARG_PTR_TO_PERCPU_BTF_ID:
		if (!reg->btf_id) {
@@ -8718,7 +8707,9 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
		 */
		meta->raw_mode = arg_type & MEM_UNINIT;
		if (arg_type & MEM_FIXED_SIZE) {
			err = check_helper_mem_access(env, regno, fn->arg_size[arg], false, meta);
			err = check_helper_mem_access(env, regno, fn->arg_size[arg],
						      arg_type & MEM_WRITE ? BPF_WRITE : BPF_READ,
						      false, meta);
			if (err)
				return err;
			if (arg_type & MEM_ALIGNED)
@@ -8726,10 +8717,16 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
		}
		break;
	case ARG_CONST_SIZE:
		err = check_mem_size_reg(env, reg, regno, false, meta);
		err = check_mem_size_reg(env, reg, regno,
					 fn->arg_type[arg - 1] & MEM_WRITE ?
					 BPF_WRITE : BPF_READ,
					 false, meta);
		break;
	case ARG_CONST_SIZE_OR_ZERO:
		err = check_mem_size_reg(env, reg, regno, true, meta);
		err = check_mem_size_reg(env, reg, regno,
					 fn->arg_type[arg - 1] & MEM_WRITE ?
					 BPF_WRITE : BPF_READ,
					 true, meta);
		break;
	case ARG_PTR_TO_DYNPTR:
		err = process_dynptr_func(env, regno, insn_idx, arg_type, 0);
Loading