diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c index c520c3c440..5ce22279ad 100644 --- a/bpf_progs/netd.c +++ b/bpf_progs/netd.c @@ -682,7 +682,7 @@ DEFINE_NETD_BPF_PROG_KVER("cgroupsock/inet_create", AID_ROOT, AID_ROOT, inet_soc } DEFINE_NETD_V_BPF_PROG_KVER("cgroupsockrelease/inet_release", AID_ROOT, AID_ROOT, - inet_socket_release, KVER_5_15) + inet_socket_release, KVER_5_10) (struct bpf_sock* sk) { uint64_t cookie = bpf_get_sk_cookie(sk); if (cookie) bpf_cookie_tag_map_delete_elem(&cookie); @@ -708,44 +708,50 @@ static __always_inline inline int check_localhost(struct bpf_sock_addr *ctx) { return 1; } -DEFINE_NETD_V_BPF_PROG_KVER("connect4/inet4_connect", AID_ROOT, AID_ROOT, inet4_connect, KVER_5_15) +DEFINE_NETD_V_BPF_PROG_KVER("connect4/inet4_connect", AID_ROOT, AID_ROOT, inet4_connect, KVER_4_14) (struct bpf_sock_addr *ctx) { return check_localhost(ctx); } -DEFINE_NETD_V_BPF_PROG_KVER("connect6/inet6_connect", AID_ROOT, AID_ROOT, inet6_connect, KVER_5_15) +DEFINE_NETD_V_BPF_PROG_KVER("connect6/inet6_connect", AID_ROOT, AID_ROOT, inet6_connect, KVER_4_14) (struct bpf_sock_addr *ctx) { return check_localhost(ctx); } -DEFINE_NETD_V_BPF_PROG_KVER("recvmsg4/udp4_recvmsg", AID_ROOT, AID_ROOT, udp4_recvmsg, KVER_5_15) +DEFINE_NETD_V_BPF_PROG_KVER("recvmsg4/udp4_recvmsg", AID_ROOT, AID_ROOT, udp4_recvmsg, KVER_4_14) (struct bpf_sock_addr *ctx) { return check_localhost(ctx); } -DEFINE_NETD_V_BPF_PROG_KVER("recvmsg6/udp6_recvmsg", AID_ROOT, AID_ROOT, udp6_recvmsg, KVER_5_15) +DEFINE_NETD_V_BPF_PROG_KVER("recvmsg6/udp6_recvmsg", AID_ROOT, AID_ROOT, udp6_recvmsg, KVER_4_14) (struct bpf_sock_addr *ctx) { return check_localhost(ctx); } -DEFINE_NETD_V_BPF_PROG_KVER("sendmsg4/udp4_sendmsg", AID_ROOT, AID_ROOT, udp4_sendmsg, KVER_5_15) +DEFINE_NETD_V_BPF_PROG_KVER("sendmsg4/udp4_sendmsg", AID_ROOT, AID_ROOT, udp4_sendmsg, KVER_4_14) (struct bpf_sock_addr *ctx) { return check_localhost(ctx); } -DEFINE_NETD_V_BPF_PROG_KVER("sendmsg6/udp6_sendmsg", AID_ROOT, AID_ROOT, udp6_sendmsg, KVER_5_15) +DEFINE_NETD_V_BPF_PROG_KVER("sendmsg6/udp6_sendmsg", AID_ROOT, AID_ROOT, udp6_sendmsg, KVER_4_14) (struct bpf_sock_addr *ctx) { return check_localhost(ctx); } -DEFINE_NETD_V_BPF_PROG_KVER("getsockopt/prog", AID_ROOT, AID_ROOT, getsockopt_prog, KVER_5_15) +DEFINE_NETD_V_BPF_PROG_KVER("getsockopt/prog", AID_ROOT, AID_ROOT, getsockopt_prog, KVER_5_4) (struct bpf_sockopt *ctx) { - return 1; + // Tell kernel to return 'original' kernel reply (instead of the bpf modified buffer) + // This is important if the answer is larger than PAGE_SIZE (max size this bpf hook can provide) + ctx->optlen = 0; + return 1; // ALLOW } -DEFINE_NETD_V_BPF_PROG_KVER("setsockopt/prog", AID_ROOT, AID_ROOT, setsockopt_prog, KVER_5_15) +DEFINE_NETD_V_BPF_PROG_KVER("setsockopt/prog", AID_ROOT, AID_ROOT, setsockopt_prog, KVER_5_4) (struct bpf_sockopt *ctx) { - return 1; + // Tell kernel to use/process original buffer provided by userspace. + // This is important if it is larger than PAGE_SIZE (max size this bpf hook can handle). + ctx->optlen = 0; + return 1; // ALLOW } LICENSE("Apache 2.0"); diff --git a/netd/BpfHandler.cpp b/netd/BpfHandler.cpp index fe2525584a..5d64ae7a6e 100644 --- a/netd/BpfHandler.cpp +++ b/netd/BpfHandler.cpp @@ -115,23 +115,27 @@ static Status initPrograms(const char* cg2_path) { } if (modules::sdklevel::IsAtLeastV()) { - if (bpf::isAtLeastKernelVersion(5, 15, 0)) { - RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_CONNECT4_PROG_PATH, - cg_fd, BPF_CGROUP_INET4_CONNECT)); - RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_CONNECT6_PROG_PATH, - cg_fd, BPF_CGROUP_INET6_CONNECT)) ; - RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_UDP4_RECVMSG_PROG_PATH, - cg_fd, BPF_CGROUP_UDP4_RECVMSG)); - RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_UDP6_RECVMSG_PROG_PATH, - cg_fd, BPF_CGROUP_UDP6_RECVMSG)); - RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_UDP4_SENDMSG_PROG_PATH, - cg_fd, BPF_CGROUP_UDP4_SENDMSG)); - RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_UDP6_SENDMSG_PROG_PATH, - cg_fd, BPF_CGROUP_UDP6_SENDMSG)); + RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_CONNECT4_PROG_PATH, + cg_fd, BPF_CGROUP_INET4_CONNECT)); + RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_CONNECT6_PROG_PATH, + cg_fd, BPF_CGROUP_INET6_CONNECT)); + RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_UDP4_RECVMSG_PROG_PATH, + cg_fd, BPF_CGROUP_UDP4_RECVMSG)); + RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_UDP6_RECVMSG_PROG_PATH, + cg_fd, BPF_CGROUP_UDP6_RECVMSG)); + RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_UDP4_SENDMSG_PROG_PATH, + cg_fd, BPF_CGROUP_UDP4_SENDMSG)); + RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_UDP6_SENDMSG_PROG_PATH, + cg_fd, BPF_CGROUP_UDP6_SENDMSG)); + + if (bpf::isAtLeastKernelVersion(5, 4, 0)) { RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_GETSOCKOPT_PROG_PATH, cg_fd, BPF_CGROUP_GETSOCKOPT)); RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_SETSOCKOPT_PROG_PATH, cg_fd, BPF_CGROUP_SETSOCKOPT)); + } + + if (bpf::isAtLeastKernelVersion(5, 10, 0)) { RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_INET_RELEASE_PROG_PATH, cg_fd, BPF_CGROUP_INET_SOCK_RELEASE)); } @@ -155,15 +159,19 @@ static Status initPrograms(const char* cg2_path) { } if (modules::sdklevel::IsAtLeastV()) { - if (bpf::isAtLeastKernelVersion(5, 15, 0)) { - if (bpf::queryProgram(cg_fd, BPF_CGROUP_INET4_CONNECT) <= 0) abort(); - if (bpf::queryProgram(cg_fd, BPF_CGROUP_INET6_CONNECT) <= 0) abort(); - if (bpf::queryProgram(cg_fd, BPF_CGROUP_UDP4_RECVMSG) <= 0) abort(); - if (bpf::queryProgram(cg_fd, BPF_CGROUP_UDP6_RECVMSG) <= 0) abort(); - if (bpf::queryProgram(cg_fd, BPF_CGROUP_UDP4_SENDMSG) <= 0) abort(); - if (bpf::queryProgram(cg_fd, BPF_CGROUP_UDP6_SENDMSG) <= 0) abort(); + if (bpf::queryProgram(cg_fd, BPF_CGROUP_INET4_CONNECT) <= 0) abort(); + if (bpf::queryProgram(cg_fd, BPF_CGROUP_INET6_CONNECT) <= 0) abort(); + if (bpf::queryProgram(cg_fd, BPF_CGROUP_UDP4_RECVMSG) <= 0) abort(); + if (bpf::queryProgram(cg_fd, BPF_CGROUP_UDP6_RECVMSG) <= 0) abort(); + if (bpf::queryProgram(cg_fd, BPF_CGROUP_UDP4_SENDMSG) <= 0) abort(); + if (bpf::queryProgram(cg_fd, BPF_CGROUP_UDP6_SENDMSG) <= 0) abort(); + + if (bpf::isAtLeastKernelVersion(5, 4, 0)) { if (bpf::queryProgram(cg_fd, BPF_CGROUP_GETSOCKOPT) <= 0) abort(); if (bpf::queryProgram(cg_fd, BPF_CGROUP_SETSOCKOPT) <= 0) abort(); + } + + if (bpf::isAtLeastKernelVersion(5, 10, 0)) { if (bpf::queryProgram(cg_fd, BPF_CGROUP_INET_SOCK_RELEASE) <= 0) abort(); } } diff --git a/tests/mts/bpf_existence_test.cpp b/tests/mts/bpf_existence_test.cpp index 3f0f3e9e4b..b02c61cdb8 100644 --- a/tests/mts/bpf_existence_test.cpp +++ b/tests/mts/bpf_existence_test.cpp @@ -147,18 +147,22 @@ static const set MAINLINE_FOR_U_5_10_PLUS = { // Provided by *current* mainline module for V+ devices static const set MAINLINE_FOR_V_PLUS = { -}; - -// Provided by *current* mainline module for V+ devices with 5.15+ kernels -static const set MAINLINE_FOR_V_5_15_PLUS = { NETD "prog_netd_connect4_inet4_connect", NETD "prog_netd_connect6_inet6_connect", NETD "prog_netd_recvmsg4_udp4_recvmsg", NETD "prog_netd_recvmsg6_udp6_recvmsg", NETD "prog_netd_sendmsg4_udp4_sendmsg", NETD "prog_netd_sendmsg6_udp6_sendmsg", +}; + +// Provided by *current* mainline module for V+ devices with 5.4+ kernels +static const set MAINLINE_FOR_V_5_4_PLUS = { NETD "prog_netd_getsockopt_prog", NETD "prog_netd_setsockopt_prog", +}; + +// Provided by *current* mainline module for U+ devices with 5.10+ kernels +static const set MAINLINE_FOR_V_5_10_PLUS = { NETD "prog_netd_cgroupsockrelease_inet_release", }; @@ -210,7 +214,8 @@ TEST_F(BpfExistenceTest, TestPrograms) { // V requires Linux Kernel 4.19+, but nothing (as yet) added or removed in V. if (IsAtLeastV()) ASSERT_TRUE(isAtLeastKernelVersion(4, 19, 0)); DO_EXPECT(IsAtLeastV(), MAINLINE_FOR_V_PLUS); - DO_EXPECT(IsAtLeastV() && isAtLeastKernelVersion(5, 15, 0), MAINLINE_FOR_V_5_15_PLUS); + DO_EXPECT(IsAtLeastV() && isAtLeastKernelVersion(5, 4, 0), MAINLINE_FOR_V_5_4_PLUS); + DO_EXPECT(IsAtLeastV() && isAtLeastKernelVersion(5, 10, 0), MAINLINE_FOR_V_5_10_PLUS); for (const auto& file : mustExist) { EXPECT_EQ(0, access(file.c_str(), R_OK)) << file << " does not exist";