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

!12754 CVE-2024-50063

Merge Pull Request from: @ci-robot 
 
PR sync from: Pu Lehui <pulehui@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/4OAAQZSR4B7U3JQOVX5JSK657SW56FSQ/ 
Xu Kuohai (2):
  bpf: Prevent tail call between progs attached to different hooks
  selftests/bpf: Add test for lsm tail call


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/IAYRIC 
 
Link:https://gitee.com/openeuler/kernel/pulls/12754

 

Reviewed-by: default avatarXu Kuohai <xukuohai@huawei.com>
Signed-off-by: default avatarYang Yingliang <yangyingliang@huawei.com>
parents 9bdf7ef6 4991277d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -945,6 +945,7 @@ struct bpf_array_aux {
	 * the same prog type and JITed flag.
	 */
	struct {
		const struct btf_type *attach_func_proto;
		spinlock_t lock;
		enum bpf_prog_type type;
		bool jited;
+15 −0
Original line number Diff line number Diff line
@@ -1779,6 +1779,7 @@ bool bpf_prog_array_compatible(struct bpf_array *array,
			       const struct bpf_prog *fp)
{
	bool ret;
	struct bpf_prog_aux *aux = fp->aux;

	if (fp->kprobe_override)
		return false;
@@ -1791,10 +1792,24 @@ bool bpf_prog_array_compatible(struct bpf_array *array,
		 */
		array->aux->owner.type  = fp->type;
		array->aux->owner.jited = fp->jited;
		array->aux->owner.attach_func_proto = aux->attach_func_proto;
		ret = true;
	} else {
		ret = array->aux->owner.type  == fp->type &&
		      array->aux->owner.jited == fp->jited;
		if (ret &&
		    array->aux->owner.attach_func_proto != aux->attach_func_proto) {
			switch (fp->type) {
			case BPF_PROG_TYPE_TRACING:
			case BPF_PROG_TYPE_LSM:
			case BPF_PROG_TYPE_EXT:
			case BPF_PROG_TYPE_STRUCT_OPS:
				ret = false;
				break;
			default:
				break;
			}
		}
	}
	spin_unlock(&array->aux->owner.lock);
	return ret;
+45 −1
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <unistd.h>

#include "lsm.skel.h"
#include "lsm_tailcall.skel.h"

char *CMD_ARGS[] = {"true", NULL};

@@ -52,7 +53,7 @@ int exec_cmd(int *monitored_pid)
	return -EINVAL;
}

void test_test_lsm(void)
static void test_lsm_basic(void)
{
	struct lsm *skel = NULL;
	int err, duration = 0;
@@ -93,3 +94,46 @@ void test_test_lsm(void)
close_prog:
	lsm__destroy(skel);
}

static void test_lsm_tailcall(void)
{
	struct lsm_tailcall *skel = NULL;
	int map_fd, prog_fd;
	int err, key;

	skel = lsm_tailcall__open_and_load();
	if (!ASSERT_OK_PTR(skel, "lsm_tailcall__skel_load"))
		goto close_prog;

	map_fd = bpf_map__fd(skel->maps.jmp_table);
	if (CHECK_FAIL(map_fd < 0))
		goto close_prog;

	prog_fd = bpf_program__fd(skel->progs.lsm_file_permission_prog);
	if (CHECK_FAIL(prog_fd < 0))
		goto close_prog;

	key = 0;
	err = bpf_map_update_elem(map_fd, &key, &prog_fd, BPF_ANY);
	if (CHECK_FAIL(!err))
		goto close_prog;

	prog_fd = bpf_program__fd(skel->progs.lsm_file_alloc_security_prog);
	if (CHECK_FAIL(prog_fd < 0))
		goto close_prog;

	err = bpf_map_update_elem(map_fd, &key, &prog_fd, BPF_ANY);
	if (CHECK_FAIL(err))
		goto close_prog;

close_prog:
	lsm_tailcall__destroy(skel);
}

void test_test_lsm(void)
{
	if (test__start_subtest("lsm_basic"))
		test_lsm_basic();
	if (test__start_subtest("lsm_tailcall"))
		test_lsm_tailcall();
}
+34 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2024 Huawei Technologies Co., Ltd */

#include "vmlinux.h"
#include <errno.h>
#include <bpf/bpf_helpers.h>

char _license[] SEC("license") = "GPL";

struct {
	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
	__uint(max_entries, 1);
	__uint(key_size, sizeof(__u32));
	__uint(value_size, sizeof(__u32));
} jmp_table SEC(".maps");

SEC("lsm/file_permission")
int lsm_file_permission_prog(void *ctx)
{
	return 0;
}

SEC("lsm/file_alloc_security")
int lsm_file_alloc_security_prog(void *ctx)
{
	return 0;
}

SEC("lsm/file_alloc_security")
int lsm_file_alloc_security_entry(void *ctx)
{
	bpf_tail_call_static(ctx, &jmp_table, 0);
	return 0;
}