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

!12871 Fix CVE-2024-47703

Merge Pull Request from: @ci-robot 
 
PR sync from: Tengda Wu <wutengda2@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/UVNAP3QMWNAJMBUYB5WQVABEI2KQZBVC/ 
This patchset is going to fix CVE-2024-47703, which
may resulting in kernel panic.

Andrii Nakryiko (2):
  bpf: enforce exact retval range on subprog/callback exit
  bpf: enforce precise retval range on program exit

Tengda Wu (2):
  bpf: Fix kabi breakage in struct bpf_func_state
  bpf: Fix kabi breakage in struct bpf_insn_access_aux

Xu Kuohai (4):
  bpf, lsm: Add disabled BPF LSM hook list
  bpf, lsm: Add check for BPF LSM return value
  bpf: Fix compare error in function retval_range_within
  selftests/bpf: Add return value checks for failed tests


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/IAYPJF 
 
Link:https://gitee.com/openeuler/kernel/pulls/12871

 

Reviewed-by: default avatarYe Weihua <yeweihua4@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents e87e8854 132895bc
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -913,6 +913,7 @@ static_assert(__BPF_REG_TYPE_MAX <= BPF_BASE_TYPE_LIMIT);
 */
struct bpf_insn_access_aux {
	enum bpf_reg_type reg_type;
	KABI_FILL_HOLE(bool is_retval) /* is accessing function return value ? */
	union {
		int ctx_field_size;
		struct {
+8 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@

#include <linux/sched.h>
#include <linux/bpf.h>
#include <linux/bpf_verifier.h>
#include <linux/lsm_hooks.h>

#ifdef CONFIG_BPF_LSM
@@ -45,6 +46,8 @@ void bpf_inode_storage_free(struct inode *inode);

void bpf_lsm_find_cgroup_shim(const struct bpf_prog *prog, bpf_func_t *bpf_func);

int bpf_lsm_get_retval_range(const struct bpf_prog *prog,
			     struct bpf_retval_range *range);
#else /* !CONFIG_BPF_LSM */

static inline bool bpf_lsm_is_sleepable_hook(u32 btf_id)
@@ -78,6 +81,11 @@ static inline void bpf_lsm_find_cgroup_shim(const struct bpf_prog *prog,
{
}

static inline int bpf_lsm_get_retval_range(const struct bpf_prog *prog,
					   struct bpf_retval_range *range)
{
	return -EOPNOTSUPP;
}
#endif /* CONFIG_BPF_LSM */

#endif /* _LINUX_BPF_LSM_H */
+7 −1
Original line number Diff line number Diff line
@@ -286,6 +286,11 @@ struct bpf_reference_state {
	KABI_RESERVE(4)
};

struct bpf_retval_range {
	s32 minval;
	s32 maxval;
};

/* state of the program:
 * type of all registers and stack info
 */
@@ -309,7 +314,8 @@ struct bpf_func_state {
	 */
	u32 async_entry_cnt;
	bool in_callback_fn;
	struct tnum callback_ret_range;
	KABI_REPLACE(struct tnum callback_ret_range,
		     struct bpf_retval_range callback_ret_range)
	bool in_async_callback_fn;
	/* For callback calling functions that limit number of possible
	 * callback executions (e.g. bpf_loop) keeps track of current
+60 −3
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@
#include <linux/lsm_hooks.h>
#include <linux/bpf_lsm.h>
#include <linux/kallsyms.h>
#include <linux/bpf_verifier.h>
#include <net/bpf_sk_storage.h>
#include <linux/bpf_local_storage.h>
#include <linux/btf_ids.h>
@@ -36,6 +35,23 @@ BTF_SET_START(bpf_lsm_hooks)
#undef LSM_HOOK
BTF_SET_END(bpf_lsm_hooks)

BTF_SET_START(bpf_lsm_disabled_hooks)
BTF_ID(func, bpf_lsm_vm_enough_memory)
BTF_ID(func, bpf_lsm_inode_need_killpriv)
BTF_ID(func, bpf_lsm_inode_getsecurity)
BTF_ID(func, bpf_lsm_inode_listsecurity)
BTF_ID(func, bpf_lsm_inode_copy_up_xattr)
BTF_ID(func, bpf_lsm_getprocattr)
BTF_ID(func, bpf_lsm_setprocattr)
#ifdef CONFIG_KEYS
BTF_ID(func, bpf_lsm_key_getsecurity)
#endif
#ifdef CONFIG_AUDIT
BTF_ID(func, bpf_lsm_audit_rule_match)
#endif
BTF_ID(func, bpf_lsm_ismaclabel)
BTF_SET_END(bpf_lsm_disabled_hooks)

/* List of LSM hooks that should operate on 'current' cgroup regardless
 * of function signature.
 */
@@ -97,15 +113,24 @@ void bpf_lsm_find_cgroup_shim(const struct bpf_prog *prog,
int bpf_lsm_verify_prog(struct bpf_verifier_log *vlog,
			const struct bpf_prog *prog)
{
	u32 btf_id = prog->aux->attach_btf_id;
	const char *func_name = prog->aux->attach_func_name;

	if (!prog->gpl_compatible) {
		bpf_log(vlog,
			"LSM programs must have a GPL compatible license\n");
		return -EINVAL;
	}

	if (!btf_id_set_contains(&bpf_lsm_hooks, prog->aux->attach_btf_id)) {
	if (btf_id_set_contains(&bpf_lsm_disabled_hooks, btf_id)) {
		bpf_log(vlog, "attach_btf_id %u points to disabled hook %s\n",
			btf_id, func_name);
		return -EINVAL;
	}

	if (!btf_id_set_contains(&bpf_lsm_hooks, btf_id)) {
		bpf_log(vlog, "attach_btf_id %u points to wrong type name %s\n",
			prog->aux->attach_btf_id, prog->aux->attach_func_name);
			btf_id, func_name);
		return -EINVAL;
	}

@@ -374,3 +399,35 @@ const struct bpf_verifier_ops lsm_verifier_ops = {
	.get_func_proto = bpf_lsm_func_proto,
	.is_valid_access = btf_ctx_access,
};

/* hooks return 0 or 1 */
BTF_SET_START(bool_lsm_hooks)
#ifdef CONFIG_SECURITY_NETWORK_XFRM
BTF_ID(func, bpf_lsm_xfrm_state_pol_flow_match)
#endif
#ifdef CONFIG_AUDIT
BTF_ID(func, bpf_lsm_audit_rule_known)
#endif
BTF_SET_END(bool_lsm_hooks)

int bpf_lsm_get_retval_range(const struct bpf_prog *prog,
			     struct bpf_retval_range *retval_range)
{
	/* no return value range for void hooks */
	if (!prog->aux->attach_func_proto->type)
		return -EINVAL;

	if (btf_id_set_contains(&bool_lsm_hooks, prog->aux->attach_btf_id)) {
		retval_range->minval = 0;
		retval_range->maxval = 1;
	} else {
		/* All other available LSM hooks, except task_prctl, return 0
		 * on success and negative error code on failure.
		 * To keep things simple, we only allow bpf progs to return 0
		 * or negative errno for task_prctl too.
		 */
		retval_range->minval = -MAX_ERRNO;
		retval_range->maxval = 0;
	}
	return 0;
}
+4 −1
Original line number Diff line number Diff line
@@ -5962,8 +5962,11 @@ bool btf_ctx_access(int off, int size, enum bpf_access_type type,

	if (arg == nr_args) {
		switch (prog->expected_attach_type) {
		case BPF_LSM_CGROUP:
		case BPF_LSM_MAC:
			/* mark we are accessing the return value */
			info->is_retval = true;
			fallthrough;
		case BPF_LSM_CGROUP:
		case BPF_TRACE_FEXIT:
			/* When LSM programs are attached to void LSM hooks
			 * they use FEXIT trampolines and when attached to
Loading