linux/tools/testing/selftests/bpf/prog_tests/lsm_cgroup.c

324 lines
9.9 KiB
C
Raw Normal View History

// SPDX-License-Identifier: GPL-2.0
#include <sys/types.h>
#include <sys/socket.h>
#include <test_progs.h>
#include <bpf/btf.h>
#include "lsm_cgroup.skel.h"
bpf: Check attach_func_proto more carefully in check_return_code Syzkaller reports the following crash: RIP: 0010:check_return_code kernel/bpf/verifier.c:10575 [inline] RIP: 0010:do_check kernel/bpf/verifier.c:12346 [inline] RIP: 0010:do_check_common+0xb3d2/0xd250 kernel/bpf/verifier.c:14610 With the following reproducer: bpf$PROG_LOAD_XDP(0x5, &(0x7f00000004c0)={0xd, 0x3, &(0x7f0000000000)=ANY=[@ANYBLOB="1800000000000019000000000000000095"], &(0x7f0000000300)='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, '\x00', 0x0, 0x2b, 0xffffffffffffffff, 0x8, 0x0, 0x0, 0x10, 0x0}, 0x80) Because we don't enforce expected_attach_type for XDP programs, we end up in hitting 'if (prog->expected_attach_type == BPF_LSM_CGROUP' part in check_return_code and follow up with testing `prog->aux->attach_func_proto->type`, but `prog->aux->attach_func_proto` is NULL. Add explicit prog_type check for the "Note, BPF_LSM_CGROUP that attach ..." condition. Also, don't skip return code check for LSM/STRUCT_OPS. The above actually brings an issue with existing selftest which tries to return EPERM from void inet_csk_clone. Fix the test (and move called_socket_clone to make sure it's not incremented in case of an error) and add a new one to explicitly verify this condition. Fixes: 69fd337a975c ("bpf: per-cgroup lsm flavor") Reported-by: syzbot+5cc0730bd4b4d2c5f152@syzkaller.appspotmail.com Signed-off-by: Stanislav Fomichev <sdf@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Martin KaFai Lau <kafai@fb.com> Link: https://lore.kernel.org/bpf/20220708175000.2603078-1-sdf@google.com
2022-07-08 10:50:00 -07:00
#include "lsm_cgroup_nonvoid.skel.h"
#include "cgroup_helpers.h"
#include "network_helpers.h"
#ifndef ENOTSUPP
#define ENOTSUPP 524
#endif
static struct btf *btf;
static __u32 query_prog_cnt(int cgroup_fd, const char *attach_func)
{
LIBBPF_OPTS(bpf_prog_query_opts, p);
int cnt = 0;
int i;
ASSERT_OK(bpf_prog_query_opts(cgroup_fd, BPF_LSM_CGROUP, &p), "prog_query");
if (!attach_func)
return p.prog_cnt;
/* When attach_func is provided, count the number of progs that
* attach to the given symbol.
*/
if (!btf)
btf = btf__load_vmlinux_btf();
if (!ASSERT_OK(libbpf_get_error(btf), "btf_vmlinux"))
return -1;
p.prog_ids = malloc(sizeof(u32) * p.prog_cnt);
p.prog_attach_flags = malloc(sizeof(u32) * p.prog_cnt);
ASSERT_OK(bpf_prog_query_opts(cgroup_fd, BPF_LSM_CGROUP, &p), "prog_query");
for (i = 0; i < p.prog_cnt; i++) {
struct bpf_prog_info info = {};
__u32 info_len = sizeof(info);
int fd;
fd = bpf_prog_get_fd_by_id(p.prog_ids[i]);
ASSERT_GE(fd, 0, "prog_get_fd_by_id");
ASSERT_OK(bpf_prog_get_info_by_fd(fd, &info, &info_len),
"prog_info_by_fd");
close(fd);
if (info.attach_btf_id ==
btf__find_by_name_kind(btf, attach_func, BTF_KIND_FUNC))
cnt++;
}
free(p.prog_ids);
free(p.prog_attach_flags);
return cnt;
}
static void test_lsm_cgroup_functional(void)
{
DECLARE_LIBBPF_OPTS(bpf_prog_attach_opts, attach_opts);
DECLARE_LIBBPF_OPTS(bpf_link_update_opts, update_opts);
int cgroup_fd = -1, cgroup_fd2 = -1, cgroup_fd3 = -1;
int listen_fd, client_fd, accepted_fd;
struct lsm_cgroup *skel = NULL;
int post_create_prog_fd2 = -1;
int post_create_prog_fd = -1;
int bind_link_fd2 = -1;
int bind_prog_fd2 = -1;
int alloc_prog_fd = -1;
int bind_prog_fd = -1;
int bind_link_fd = -1;
int clone_prog_fd = -1;
int err, fd, prio;
socklen_t socklen;
cgroup_fd3 = test__join_cgroup("/sock_policy_empty");
if (!ASSERT_GE(cgroup_fd3, 0, "create empty cgroup"))
goto close_cgroup;
cgroup_fd2 = test__join_cgroup("/sock_policy_reuse");
if (!ASSERT_GE(cgroup_fd2, 0, "create cgroup for reuse"))
goto close_cgroup;
cgroup_fd = test__join_cgroup("/sock_policy");
if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup"))
goto close_cgroup;
skel = lsm_cgroup__open_and_load();
if (!ASSERT_OK_PTR(skel, "open_and_load"))
goto close_cgroup;
post_create_prog_fd = bpf_program__fd(skel->progs.socket_post_create);
post_create_prog_fd2 = bpf_program__fd(skel->progs.socket_post_create2);
bind_prog_fd = bpf_program__fd(skel->progs.socket_bind);
bind_prog_fd2 = bpf_program__fd(skel->progs.socket_bind2);
alloc_prog_fd = bpf_program__fd(skel->progs.socket_alloc);
clone_prog_fd = bpf_program__fd(skel->progs.socket_clone);
ASSERT_EQ(query_prog_cnt(cgroup_fd, "bpf_lsm_sk_alloc_security"), 0, "prog count");
ASSERT_EQ(query_prog_cnt(cgroup_fd, NULL), 0, "total prog count");
err = bpf_prog_attach(alloc_prog_fd, cgroup_fd, BPF_LSM_CGROUP, 0);
if (err == -ENOTSUPP) {
test__skip();
goto close_cgroup;
}
if (!ASSERT_OK(err, "attach alloc_prog_fd"))
goto detach_cgroup;
ASSERT_EQ(query_prog_cnt(cgroup_fd, "bpf_lsm_sk_alloc_security"), 1, "prog count");
ASSERT_EQ(query_prog_cnt(cgroup_fd, NULL), 1, "total prog count");
ASSERT_EQ(query_prog_cnt(cgroup_fd, "bpf_lsm_inet_csk_clone"), 0, "prog count");
err = bpf_prog_attach(clone_prog_fd, cgroup_fd, BPF_LSM_CGROUP, 0);
if (!ASSERT_OK(err, "attach clone_prog_fd"))
goto detach_cgroup;
ASSERT_EQ(query_prog_cnt(cgroup_fd, "bpf_lsm_inet_csk_clone"), 1, "prog count");
ASSERT_EQ(query_prog_cnt(cgroup_fd, NULL), 2, "total prog count");
/* Make sure replacing works. */
ASSERT_EQ(query_prog_cnt(cgroup_fd, "bpf_lsm_socket_post_create"), 0, "prog count");
err = bpf_prog_attach(post_create_prog_fd, cgroup_fd,
BPF_LSM_CGROUP, 0);
if (!ASSERT_OK(err, "attach post_create_prog_fd"))
goto detach_cgroup;
ASSERT_EQ(query_prog_cnt(cgroup_fd, "bpf_lsm_socket_post_create"), 1, "prog count");
ASSERT_EQ(query_prog_cnt(cgroup_fd, NULL), 3, "total prog count");
attach_opts.replace_prog_fd = post_create_prog_fd;
err = bpf_prog_attach_opts(post_create_prog_fd2, cgroup_fd,
BPF_LSM_CGROUP, &attach_opts);
if (!ASSERT_OK(err, "prog replace post_create_prog_fd"))
goto detach_cgroup;
ASSERT_EQ(query_prog_cnt(cgroup_fd, "bpf_lsm_socket_post_create"), 1, "prog count");
ASSERT_EQ(query_prog_cnt(cgroup_fd, NULL), 3, "total prog count");
/* Try the same attach/replace via link API. */
ASSERT_EQ(query_prog_cnt(cgroup_fd, "bpf_lsm_socket_bind"), 0, "prog count");
bind_link_fd = bpf_link_create(bind_prog_fd, cgroup_fd,
BPF_LSM_CGROUP, NULL);
if (!ASSERT_GE(bind_link_fd, 0, "link create bind_prog_fd"))
goto detach_cgroup;
ASSERT_EQ(query_prog_cnt(cgroup_fd, "bpf_lsm_socket_bind"), 1, "prog count");
ASSERT_EQ(query_prog_cnt(cgroup_fd, NULL), 4, "total prog count");
update_opts.old_prog_fd = bind_prog_fd;
update_opts.flags = BPF_F_REPLACE;
err = bpf_link_update(bind_link_fd, bind_prog_fd2, &update_opts);
if (!ASSERT_OK(err, "link update bind_prog_fd"))
goto detach_cgroup;
ASSERT_EQ(query_prog_cnt(cgroup_fd, "bpf_lsm_socket_bind"), 1, "prog count");
ASSERT_EQ(query_prog_cnt(cgroup_fd, NULL), 4, "total prog count");
/* Attach another instance of bind program to another cgroup.
* This should trigger the reuse of the trampoline shim (two
* programs attaching to the same btf_id).
*/
ASSERT_EQ(query_prog_cnt(cgroup_fd, "bpf_lsm_socket_bind"), 1, "prog count");
ASSERT_EQ(query_prog_cnt(cgroup_fd2, "bpf_lsm_socket_bind"), 0, "prog count");
bind_link_fd2 = bpf_link_create(bind_prog_fd2, cgroup_fd2,
BPF_LSM_CGROUP, NULL);
if (!ASSERT_GE(bind_link_fd2, 0, "link create bind_prog_fd2"))
goto detach_cgroup;
ASSERT_EQ(query_prog_cnt(cgroup_fd2, "bpf_lsm_socket_bind"), 1, "prog count");
ASSERT_EQ(query_prog_cnt(cgroup_fd, NULL), 4, "total prog count");
ASSERT_EQ(query_prog_cnt(cgroup_fd2, NULL), 1, "total prog count");
fd = socket(AF_UNIX, SOCK_STREAM, 0);
selftests/bpf: fix memory leak of lsm_cgroup kmemleak reports this issue: unreferenced object 0xffff88810b7835c0 (size 32): comm "test_progs", pid 270, jiffies 4294969007 (age 1621.315s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 03 00 00 00 03 00 00 00 0f 00 00 00 00 00 00 00 ................ backtrace: [<00000000376cdeab>] kmalloc_trace+0x27/0x110 [<000000003bcdb3b6>] selinux_sk_alloc_security+0x66/0x110 [<000000003959008f>] security_sk_alloc+0x47/0x80 [<00000000e7bc6668>] sk_prot_alloc+0xbd/0x1a0 [<0000000002d6343a>] sk_alloc+0x3b/0x940 [<000000009812a46d>] unix_create1+0x8f/0x3d0 [<000000005ed0976b>] unix_create+0xa1/0x150 [<0000000086a1d27f>] __sock_create+0x233/0x4a0 [<00000000cffe3a73>] __sys_socket_create.part.0+0xaa/0x110 [<0000000007c63f20>] __sys_socket+0x49/0xf0 [<00000000b08753c8>] __x64_sys_socket+0x42/0x50 [<00000000b56e26b3>] do_syscall_64+0x3b/0x90 [<000000009b4871b8>] entry_SYSCALL_64_after_hwframe+0x63/0xcd The issue occurs in the following scenarios: unix_create1() sk_alloc() sk_prot_alloc() security_sk_alloc() call_int_hook() hlist_for_each_entry() entry1->hook.sk_alloc_security <-- selinux_sk_alloc_security() succeeded, <-- sk->security alloced here. entry2->hook.sk_alloc_security <-- bpf_lsm_sk_alloc_security() failed goto out_free; ... <-- the sk->security not freed, memleak The core problem is that the LSM is not yet fully stacked (work is actively going on in this space) which means that some LSM hooks do not support multiple LSMs at the same time. To fix, skip the "EPERM" test when it runs in the environments that already have non-bpf lsms installed Fixes: dca85aac8895 ("selftests/bpf: lsm_cgroup functional test") Signed-off-by: Wang Yufen <wangyufen@huawei.com> Cc: Stanislav Fomichev <sdf@google.com> Acked-by: Stanislav Fomichev <sdf@google.com> Link: https://lore.kernel.org/r/1668482980-16163-1-git-send-email-wangyufen@huawei.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
2022-11-15 11:29:40 +08:00
if (!(skel->kconfig->CONFIG_SECURITY_APPARMOR
|| skel->kconfig->CONFIG_SECURITY_SELINUX
|| skel->kconfig->CONFIG_SECURITY_SMACK))
/* AF_UNIX is prohibited. */
ASSERT_LT(fd, 0, "socket(AF_UNIX)");
close(fd);
/* AF_INET6 gets default policy (sk_priority). */
fd = socket(AF_INET6, SOCK_STREAM, 0);
if (!ASSERT_GE(fd, 0, "socket(SOCK_STREAM)"))
goto detach_cgroup;
prio = 0;
socklen = sizeof(prio);
ASSERT_GE(getsockopt(fd, SOL_SOCKET, SO_PRIORITY, &prio, &socklen), 0,
"getsockopt");
ASSERT_EQ(prio, 123, "sk_priority");
close(fd);
/* TX-only AF_PACKET is allowed. */
ASSERT_LT(socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)), 0,
"socket(AF_PACKET, ..., ETH_P_ALL)");
fd = socket(AF_PACKET, SOCK_RAW, 0);
ASSERT_GE(fd, 0, "socket(AF_PACKET, ..., 0)");
/* TX-only AF_PACKET can not be rebound. */
struct sockaddr_ll sa = {
.sll_family = AF_PACKET,
.sll_protocol = htons(ETH_P_ALL),
};
ASSERT_LT(bind(fd, (struct sockaddr *)&sa, sizeof(sa)), 0,
"bind(ETH_P_ALL)");
close(fd);
/* Trigger passive open. */
listen_fd = start_server(AF_INET6, SOCK_STREAM, "::1", 0, 0);
ASSERT_GE(listen_fd, 0, "start_server");
client_fd = connect_to_fd(listen_fd, 0);
ASSERT_GE(client_fd, 0, "connect_to_fd");
accepted_fd = accept(listen_fd, NULL, NULL);
ASSERT_GE(accepted_fd, 0, "accept");
prio = 0;
socklen = sizeof(prio);
ASSERT_GE(getsockopt(accepted_fd, SOL_SOCKET, SO_PRIORITY, &prio, &socklen), 0,
"getsockopt");
ASSERT_EQ(prio, 234, "sk_priority");
/* These are replaced and never called. */
ASSERT_EQ(skel->bss->called_socket_post_create, 0, "called_create");
ASSERT_EQ(skel->bss->called_socket_bind, 0, "called_bind");
/* AF_INET6+SOCK_STREAM
* AF_PACKET+SOCK_RAW
selftests/bpf: fix memory leak of lsm_cgroup kmemleak reports this issue: unreferenced object 0xffff88810b7835c0 (size 32): comm "test_progs", pid 270, jiffies 4294969007 (age 1621.315s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 03 00 00 00 03 00 00 00 0f 00 00 00 00 00 00 00 ................ backtrace: [<00000000376cdeab>] kmalloc_trace+0x27/0x110 [<000000003bcdb3b6>] selinux_sk_alloc_security+0x66/0x110 [<000000003959008f>] security_sk_alloc+0x47/0x80 [<00000000e7bc6668>] sk_prot_alloc+0xbd/0x1a0 [<0000000002d6343a>] sk_alloc+0x3b/0x940 [<000000009812a46d>] unix_create1+0x8f/0x3d0 [<000000005ed0976b>] unix_create+0xa1/0x150 [<0000000086a1d27f>] __sock_create+0x233/0x4a0 [<00000000cffe3a73>] __sys_socket_create.part.0+0xaa/0x110 [<0000000007c63f20>] __sys_socket+0x49/0xf0 [<00000000b08753c8>] __x64_sys_socket+0x42/0x50 [<00000000b56e26b3>] do_syscall_64+0x3b/0x90 [<000000009b4871b8>] entry_SYSCALL_64_after_hwframe+0x63/0xcd The issue occurs in the following scenarios: unix_create1() sk_alloc() sk_prot_alloc() security_sk_alloc() call_int_hook() hlist_for_each_entry() entry1->hook.sk_alloc_security <-- selinux_sk_alloc_security() succeeded, <-- sk->security alloced here. entry2->hook.sk_alloc_security <-- bpf_lsm_sk_alloc_security() failed goto out_free; ... <-- the sk->security not freed, memleak The core problem is that the LSM is not yet fully stacked (work is actively going on in this space) which means that some LSM hooks do not support multiple LSMs at the same time. To fix, skip the "EPERM" test when it runs in the environments that already have non-bpf lsms installed Fixes: dca85aac8895 ("selftests/bpf: lsm_cgroup functional test") Signed-off-by: Wang Yufen <wangyufen@huawei.com> Cc: Stanislav Fomichev <sdf@google.com> Acked-by: Stanislav Fomichev <sdf@google.com> Link: https://lore.kernel.org/r/1668482980-16163-1-git-send-email-wangyufen@huawei.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
2022-11-15 11:29:40 +08:00
* AF_UNIX+SOCK_RAW if already have non-bpf lsms installed
* listen_fd
* client_fd
* accepted_fd
*/
selftests/bpf: fix memory leak of lsm_cgroup kmemleak reports this issue: unreferenced object 0xffff88810b7835c0 (size 32): comm "test_progs", pid 270, jiffies 4294969007 (age 1621.315s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 03 00 00 00 03 00 00 00 0f 00 00 00 00 00 00 00 ................ backtrace: [<00000000376cdeab>] kmalloc_trace+0x27/0x110 [<000000003bcdb3b6>] selinux_sk_alloc_security+0x66/0x110 [<000000003959008f>] security_sk_alloc+0x47/0x80 [<00000000e7bc6668>] sk_prot_alloc+0xbd/0x1a0 [<0000000002d6343a>] sk_alloc+0x3b/0x940 [<000000009812a46d>] unix_create1+0x8f/0x3d0 [<000000005ed0976b>] unix_create+0xa1/0x150 [<0000000086a1d27f>] __sock_create+0x233/0x4a0 [<00000000cffe3a73>] __sys_socket_create.part.0+0xaa/0x110 [<0000000007c63f20>] __sys_socket+0x49/0xf0 [<00000000b08753c8>] __x64_sys_socket+0x42/0x50 [<00000000b56e26b3>] do_syscall_64+0x3b/0x90 [<000000009b4871b8>] entry_SYSCALL_64_after_hwframe+0x63/0xcd The issue occurs in the following scenarios: unix_create1() sk_alloc() sk_prot_alloc() security_sk_alloc() call_int_hook() hlist_for_each_entry() entry1->hook.sk_alloc_security <-- selinux_sk_alloc_security() succeeded, <-- sk->security alloced here. entry2->hook.sk_alloc_security <-- bpf_lsm_sk_alloc_security() failed goto out_free; ... <-- the sk->security not freed, memleak The core problem is that the LSM is not yet fully stacked (work is actively going on in this space) which means that some LSM hooks do not support multiple LSMs at the same time. To fix, skip the "EPERM" test when it runs in the environments that already have non-bpf lsms installed Fixes: dca85aac8895 ("selftests/bpf: lsm_cgroup functional test") Signed-off-by: Wang Yufen <wangyufen@huawei.com> Cc: Stanislav Fomichev <sdf@google.com> Acked-by: Stanislav Fomichev <sdf@google.com> Link: https://lore.kernel.org/r/1668482980-16163-1-git-send-email-wangyufen@huawei.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
2022-11-15 11:29:40 +08:00
if (skel->kconfig->CONFIG_SECURITY_APPARMOR
|| skel->kconfig->CONFIG_SECURITY_SELINUX
|| skel->kconfig->CONFIG_SECURITY_SMACK)
/* AF_UNIX+SOCK_RAW if already have non-bpf lsms installed */
ASSERT_EQ(skel->bss->called_socket_post_create2, 6, "called_create2");
else
ASSERT_EQ(skel->bss->called_socket_post_create2, 5, "called_create2");
/* start_server
* bind(ETH_P_ALL)
*/
ASSERT_EQ(skel->bss->called_socket_bind2, 2, "called_bind2");
/* Single accept(). */
ASSERT_EQ(skel->bss->called_socket_clone, 1, "called_clone");
/* AF_UNIX+SOCK_STREAM (failed)
* AF_INET6+SOCK_STREAM
* AF_PACKET+SOCK_RAW (failed)
* AF_PACKET+SOCK_RAW
* listen_fd
* client_fd
* accepted_fd
*/
ASSERT_EQ(skel->bss->called_socket_alloc, 7, "called_alloc");
close(listen_fd);
close(client_fd);
close(accepted_fd);
/* Make sure other cgroup doesn't trigger the programs. */
if (!ASSERT_OK(join_cgroup("/sock_policy_empty"), "join root cgroup"))
goto detach_cgroup;
fd = socket(AF_INET6, SOCK_STREAM, 0);
if (!ASSERT_GE(fd, 0, "socket(SOCK_STREAM)"))
goto detach_cgroup;
prio = 0;
socklen = sizeof(prio);
ASSERT_GE(getsockopt(fd, SOL_SOCKET, SO_PRIORITY, &prio, &socklen), 0,
"getsockopt");
ASSERT_EQ(prio, 0, "sk_priority");
close(fd);
detach_cgroup:
ASSERT_GE(bpf_prog_detach2(post_create_prog_fd2, cgroup_fd,
BPF_LSM_CGROUP), 0, "detach_create");
close(bind_link_fd);
/* Don't close bind_link_fd2, exercise cgroup release cleanup. */
ASSERT_GE(bpf_prog_detach2(alloc_prog_fd, cgroup_fd,
BPF_LSM_CGROUP), 0, "detach_alloc");
ASSERT_GE(bpf_prog_detach2(clone_prog_fd, cgroup_fd,
BPF_LSM_CGROUP), 0, "detach_clone");
close_cgroup:
close(cgroup_fd);
close(cgroup_fd2);
close(cgroup_fd3);
lsm_cgroup__destroy(skel);
}
bpf: Check attach_func_proto more carefully in check_return_code Syzkaller reports the following crash: RIP: 0010:check_return_code kernel/bpf/verifier.c:10575 [inline] RIP: 0010:do_check kernel/bpf/verifier.c:12346 [inline] RIP: 0010:do_check_common+0xb3d2/0xd250 kernel/bpf/verifier.c:14610 With the following reproducer: bpf$PROG_LOAD_XDP(0x5, &(0x7f00000004c0)={0xd, 0x3, &(0x7f0000000000)=ANY=[@ANYBLOB="1800000000000019000000000000000095"], &(0x7f0000000300)='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, '\x00', 0x0, 0x2b, 0xffffffffffffffff, 0x8, 0x0, 0x0, 0x10, 0x0}, 0x80) Because we don't enforce expected_attach_type for XDP programs, we end up in hitting 'if (prog->expected_attach_type == BPF_LSM_CGROUP' part in check_return_code and follow up with testing `prog->aux->attach_func_proto->type`, but `prog->aux->attach_func_proto` is NULL. Add explicit prog_type check for the "Note, BPF_LSM_CGROUP that attach ..." condition. Also, don't skip return code check for LSM/STRUCT_OPS. The above actually brings an issue with existing selftest which tries to return EPERM from void inet_csk_clone. Fix the test (and move called_socket_clone to make sure it's not incremented in case of an error) and add a new one to explicitly verify this condition. Fixes: 69fd337a975c ("bpf: per-cgroup lsm flavor") Reported-by: syzbot+5cc0730bd4b4d2c5f152@syzkaller.appspotmail.com Signed-off-by: Stanislav Fomichev <sdf@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Martin KaFai Lau <kafai@fb.com> Link: https://lore.kernel.org/bpf/20220708175000.2603078-1-sdf@google.com
2022-07-08 10:50:00 -07:00
static void test_lsm_cgroup_nonvoid(void)
{
struct lsm_cgroup_nonvoid *skel = NULL;
skel = lsm_cgroup_nonvoid__open_and_load();
ASSERT_NULL(skel, "open succeeds");
lsm_cgroup_nonvoid__destroy(skel);
}
void test_lsm_cgroup(void)
{
if (test__start_subtest("functional"))
test_lsm_cgroup_functional();
bpf: Check attach_func_proto more carefully in check_return_code Syzkaller reports the following crash: RIP: 0010:check_return_code kernel/bpf/verifier.c:10575 [inline] RIP: 0010:do_check kernel/bpf/verifier.c:12346 [inline] RIP: 0010:do_check_common+0xb3d2/0xd250 kernel/bpf/verifier.c:14610 With the following reproducer: bpf$PROG_LOAD_XDP(0x5, &(0x7f00000004c0)={0xd, 0x3, &(0x7f0000000000)=ANY=[@ANYBLOB="1800000000000019000000000000000095"], &(0x7f0000000300)='GPL\x00', 0x0, 0x0, 0x0, 0x0, 0x0, '\x00', 0x0, 0x2b, 0xffffffffffffffff, 0x8, 0x0, 0x0, 0x10, 0x0}, 0x80) Because we don't enforce expected_attach_type for XDP programs, we end up in hitting 'if (prog->expected_attach_type == BPF_LSM_CGROUP' part in check_return_code and follow up with testing `prog->aux->attach_func_proto->type`, but `prog->aux->attach_func_proto` is NULL. Add explicit prog_type check for the "Note, BPF_LSM_CGROUP that attach ..." condition. Also, don't skip return code check for LSM/STRUCT_OPS. The above actually brings an issue with existing selftest which tries to return EPERM from void inet_csk_clone. Fix the test (and move called_socket_clone to make sure it's not incremented in case of an error) and add a new one to explicitly verify this condition. Fixes: 69fd337a975c ("bpf: per-cgroup lsm flavor") Reported-by: syzbot+5cc0730bd4b4d2c5f152@syzkaller.appspotmail.com Signed-off-by: Stanislav Fomichev <sdf@google.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Martin KaFai Lau <kafai@fb.com> Link: https://lore.kernel.org/bpf/20220708175000.2603078-1-sdf@google.com
2022-07-08 10:50:00 -07:00
if (test__start_subtest("nonvoid"))
test_lsm_cgroup_nonvoid();
btf__free(btf);
}