From 22db5905803b6bbaf3b84fee412ea1f3415ce8bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20=C5=BBenczykowski?= Date: Fri, 10 May 2024 06:44:08 -0700 Subject: [PATCH] bpf: attach a *bunch* more cgroup hooks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We attach trivial programs to: {connect,recvmsg,sendmsg}{4,6} inet_release {g,s}etsockopt Test: TreeHugger Signed-off-by: Maciej Żenczykowski Change-Id: Ifd3a6dff20a5881f4fdb5d1b4b7b03a55988fd74 --- bpf_progs/bpf_net_helpers.h | 1 + bpf_progs/netd.c | 74 ++++++++++++++++++- bpf_progs/netd.h | 11 ++- netbpfload/loader.cpp | 54 +++++++------- netd/BpfHandler.cpp | 41 +++++++++- .../android/server/ConnectivityService.java | 34 +++++++++ .../com/android/net/module/util/BpfUtils.java | 9 +++ .../bpf_headers/include/bpf/bpf_helpers.h | 1 + tests/mts/bpf_existence_test.cpp | 19 +++++ 9 files changed, 214 insertions(+), 30 deletions(-) diff --git a/bpf_progs/bpf_net_helpers.h b/bpf_progs/bpf_net_helpers.h index f3c7de513d..1511ee56c0 100644 --- a/bpf_progs/bpf_net_helpers.h +++ b/bpf_progs/bpf_net_helpers.h @@ -35,6 +35,7 @@ // this returns 0 iff skb->sk is NULL static uint64_t (*bpf_get_socket_cookie)(struct __sk_buff* skb) = (void*)BPF_FUNC_get_socket_cookie; +static uint64_t (*bpf_get_sk_cookie)(struct bpf_sock* sk) = (void*)BPF_FUNC_get_socket_cookie; static uint32_t (*bpf_get_socket_uid)(struct __sk_buff* skb) = (void*)BPF_FUNC_get_socket_uid; diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c index bd7b8b42f1..c520c3c440 100644 --- a/bpf_progs/netd.c +++ b/bpf_progs/netd.c @@ -142,6 +142,11 @@ DEFINE_BPF_MAP_RO_NETD(data_saver_enabled_map, ARRAY, uint32_t, bool, #define DEFINE_NETD_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \ DEFINE_NETD_BPF_PROG_KVER(SECTION_NAME, prog_uid, prog_gid, the_prog, KVER_NONE) +#define DEFINE_NETD_V_BPF_PROG_KVER(SECTION_NAME, prog_uid, prog_gid, the_prog, minKV) \ + DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, minKV, \ + KVER_INF, BPFLOADER_MAINLINE_V_VERSION, BPFLOADER_MAX_VER, MANDATORY, \ + "fs_bpf_netd_readonly", "", LOAD_ON_ENG, LOAD_ON_USER, LOAD_ON_USERDEBUG) + // programs that only need to be usable by the system server #define DEFINE_SYS_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \ DEFINE_BPF_PROG_EXT(SECTION_NAME, prog_uid, prog_gid, the_prog, KVER_NONE, KVER_INF, \ @@ -669,13 +674,80 @@ static __always_inline inline uint8_t get_app_permissions() { return permissions ? *permissions : BPF_PERMISSION_INTERNET; } -DEFINE_NETD_BPF_PROG_KVER("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_create, +DEFINE_NETD_BPF_PROG_KVER("cgroupsock/inet_create", AID_ROOT, AID_ROOT, inet_socket_create, KVER_4_14) (struct bpf_sock* sk) { // A return value of 1 means allow, everything else means deny. return (get_app_permissions() & BPF_PERMISSION_INTERNET) ? 1 : 0; } +DEFINE_NETD_V_BPF_PROG_KVER("cgroupsockrelease/inet_release", AID_ROOT, AID_ROOT, + inet_socket_release, KVER_5_15) +(struct bpf_sock* sk) { + uint64_t cookie = bpf_get_sk_cookie(sk); + if (cookie) bpf_cookie_tag_map_delete_elem(&cookie); + + return 1; +} + +static __always_inline inline int check_localhost(struct bpf_sock_addr *ctx) { + // See include/uapi/linux/bpf.h: + // + // struct bpf_sock_addr { + // __u32 user_family; // R: 4 byte + // __u32 user_ip4; // BE, R: 1,2,4-byte, W: 4-byte + // __u32 user_ip6[4]; // BE, R: 1,2,4,8-byte, W: 4,8-byte + // __u32 user_port; // BE, R: 1,2,4-byte, W: 4-byte + // __u32 family; // R: 4 byte + // __u32 type; // R: 4 byte + // __u32 protocol; // R: 4 byte + // __u32 msg_src_ip4; // BE, R: 1,2,4-byte, W: 4-byte + // __u32 msg_src_ip6[4]; // BE, R: 1,2,4,8-byte, W: 4,8-byte + // __bpf_md_ptr(struct bpf_sock *, sk); + // }; + return 1; +} + +DEFINE_NETD_V_BPF_PROG_KVER("connect4/inet4_connect", AID_ROOT, AID_ROOT, inet4_connect, KVER_5_15) +(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) +(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) +(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) +(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) +(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) +(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) +(struct bpf_sockopt *ctx) { + return 1; +} + +DEFINE_NETD_V_BPF_PROG_KVER("setsockopt/prog", AID_ROOT, AID_ROOT, setsockopt_prog, KVER_5_15) +(struct bpf_sockopt *ctx) { + return 1; +} + LICENSE("Apache 2.0"); CRITICAL("Connectivity and netd"); DISABLE_BTF_ON_USER_BUILDS(); diff --git a/bpf_progs/netd.h b/bpf_progs/netd.h index 8a56b4a288..332979baf7 100644 --- a/bpf_progs/netd.h +++ b/bpf_progs/netd.h @@ -155,7 +155,16 @@ ASSERT_STRING_EQUAL(XT_BPF_EGRESS_PROG_PATH, BPF_NETD_PATH "prog_netd_skfilte ASSERT_STRING_EQUAL(XT_BPF_ALLOWLIST_PROG_PATH, BPF_NETD_PATH "prog_netd_skfilter_allowlist_xtbpf"); ASSERT_STRING_EQUAL(XT_BPF_DENYLIST_PROG_PATH, BPF_NETD_PATH "prog_netd_skfilter_denylist_xtbpf"); -#define CGROUP_SOCKET_PROG_PATH BPF_NETD_PATH "prog_netd_cgroupsock_inet_create" +#define CGROUP_INET_CREATE_PROG_PATH BPF_NETD_PATH "prog_netd_cgroupsock_inet_create" +#define CGROUP_INET_RELEASE_PROG_PATH BPF_NETD_PATH "prog_netd_cgroupsockrelease_inet_release" +#define CGROUP_CONNECT4_PROG_PATH BPF_NETD_PATH "prog_netd_connect4_inet4_connect" +#define CGROUP_CONNECT6_PROG_PATH BPF_NETD_PATH "prog_netd_connect6_inet6_connect" +#define CGROUP_UDP4_RECVMSG_PROG_PATH BPF_NETD_PATH "prog_netd_recvmsg4_udp4_recvmsg" +#define CGROUP_UDP6_RECVMSG_PROG_PATH BPF_NETD_PATH "prog_netd_recvmsg6_udp6_recvmsg" +#define CGROUP_UDP4_SENDMSG_PROG_PATH BPF_NETD_PATH "prog_netd_sendmsg4_udp4_sendmsg" +#define CGROUP_UDP6_SENDMSG_PROG_PATH BPF_NETD_PATH "prog_netd_sendmsg6_udp6_sendmsg" +#define CGROUP_GETSOCKOPT_PROG_PATH BPF_NETD_PATH "prog_netd_getsockopt_prog" +#define CGROUP_SETSOCKOPT_PROG_PATH BPF_NETD_PATH "prog_netd_setsockopt_prog" #define TC_BPF_INGRESS_ACCOUNT_PROG_NAME "prog_netd_schedact_ingress_account" #define TC_BPF_INGRESS_ACCOUNT_PROG_PATH BPF_NETD_PATH TC_BPF_INGRESS_ACCOUNT_PROG_NAME diff --git a/netbpfload/loader.cpp b/netbpfload/loader.cpp index 72ff172d1a..bb7c56f447 100644 --- a/netbpfload/loader.cpp +++ b/netbpfload/loader.cpp @@ -165,32 +165,34 @@ typedef struct { * since they are less stable abi/api and may conflict with platform uses of bpf. */ sectionType sectionNameTypes[] = { - {"bind4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_BIND}, - {"bind6/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET6_BIND}, - {"cgroupskb/", BPF_PROG_TYPE_CGROUP_SKB, BPF_ATTACH_TYPE_UNSPEC}, - {"cgroupsock/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_ATTACH_TYPE_UNSPEC}, - {"connect4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_CONNECT}, - {"connect6/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET6_CONNECT}, - {"egress/", BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_EGRESS}, - {"getsockopt/", BPF_PROG_TYPE_CGROUP_SOCKOPT, BPF_CGROUP_GETSOCKOPT}, - {"ingress/", BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_INGRESS}, - {"lwt_in/", BPF_PROG_TYPE_LWT_IN, BPF_ATTACH_TYPE_UNSPEC}, - {"lwt_out/", BPF_PROG_TYPE_LWT_OUT, BPF_ATTACH_TYPE_UNSPEC}, - {"lwt_seg6local/", BPF_PROG_TYPE_LWT_SEG6LOCAL, BPF_ATTACH_TYPE_UNSPEC}, - {"lwt_xmit/", BPF_PROG_TYPE_LWT_XMIT, BPF_ATTACH_TYPE_UNSPEC}, - {"postbind4/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET4_POST_BIND}, - {"postbind6/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET6_POST_BIND}, - {"recvmsg4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_UDP4_RECVMSG}, - {"recvmsg6/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_UDP6_RECVMSG}, - {"schedact/", BPF_PROG_TYPE_SCHED_ACT, BPF_ATTACH_TYPE_UNSPEC}, - {"schedcls/", BPF_PROG_TYPE_SCHED_CLS, BPF_ATTACH_TYPE_UNSPEC}, - {"sendmsg4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_UDP4_SENDMSG}, - {"sendmsg6/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_UDP6_SENDMSG}, - {"setsockopt/", BPF_PROG_TYPE_CGROUP_SOCKOPT, BPF_CGROUP_SETSOCKOPT}, - {"skfilter/", BPF_PROG_TYPE_SOCKET_FILTER, BPF_ATTACH_TYPE_UNSPEC}, - {"sockops/", BPF_PROG_TYPE_SOCK_OPS, BPF_CGROUP_SOCK_OPS}, - {"sysctl", BPF_PROG_TYPE_CGROUP_SYSCTL, BPF_CGROUP_SYSCTL}, - {"xdp/", BPF_PROG_TYPE_XDP, BPF_ATTACH_TYPE_UNSPEC}, + {"bind4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_BIND}, + {"bind6/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET6_BIND}, + {"cgroupskb/", BPF_PROG_TYPE_CGROUP_SKB, BPF_ATTACH_TYPE_UNSPEC}, + {"cgroupsock/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_ATTACH_TYPE_UNSPEC}, + {"cgroupsockcreate/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET_SOCK_CREATE}, + {"cgroupsockrelease/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET_SOCK_RELEASE}, + {"connect4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_CONNECT}, + {"connect6/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET6_CONNECT}, + {"egress/", BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_EGRESS}, + {"getsockopt/", BPF_PROG_TYPE_CGROUP_SOCKOPT, BPF_CGROUP_GETSOCKOPT}, + {"ingress/", BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_INGRESS}, + {"lwt_in/", BPF_PROG_TYPE_LWT_IN, BPF_ATTACH_TYPE_UNSPEC}, + {"lwt_out/", BPF_PROG_TYPE_LWT_OUT, BPF_ATTACH_TYPE_UNSPEC}, + {"lwt_seg6local/", BPF_PROG_TYPE_LWT_SEG6LOCAL, BPF_ATTACH_TYPE_UNSPEC}, + {"lwt_xmit/", BPF_PROG_TYPE_LWT_XMIT, BPF_ATTACH_TYPE_UNSPEC}, + {"postbind4/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET4_POST_BIND}, + {"postbind6/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET6_POST_BIND}, + {"recvmsg4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_UDP4_RECVMSG}, + {"recvmsg6/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_UDP6_RECVMSG}, + {"schedact/", BPF_PROG_TYPE_SCHED_ACT, BPF_ATTACH_TYPE_UNSPEC}, + {"schedcls/", BPF_PROG_TYPE_SCHED_CLS, BPF_ATTACH_TYPE_UNSPEC}, + {"sendmsg4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_UDP4_SENDMSG}, + {"sendmsg6/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_UDP6_SENDMSG}, + {"setsockopt/", BPF_PROG_TYPE_CGROUP_SOCKOPT, BPF_CGROUP_SETSOCKOPT}, + {"skfilter/", BPF_PROG_TYPE_SOCKET_FILTER, BPF_ATTACH_TYPE_UNSPEC}, + {"sockops/", BPF_PROG_TYPE_SOCK_OPS, BPF_CGROUP_SOCK_OPS}, + {"sysctl", BPF_PROG_TYPE_CGROUP_SYSCTL, BPF_CGROUP_SYSCTL}, + {"xdp/", BPF_PROG_TYPE_XDP, BPF_ATTACH_TYPE_UNSPEC}, }; typedef struct { diff --git a/netd/BpfHandler.cpp b/netd/BpfHandler.cpp index f884beb29e..fe2525584a 100644 --- a/netd/BpfHandler.cpp +++ b/netd/BpfHandler.cpp @@ -110,8 +110,31 @@ static Status initPrograms(const char* cg2_path) { // TODO: delete the if statement once all devices should support cgroup // socket filter (ie. the minimum kernel version required is 4.14). if (bpf::isAtLeastKernelVersion(4, 14, 0)) { - RETURN_IF_NOT_OK( - attachProgramToCgroup(CGROUP_SOCKET_PROG_PATH, cg_fd, BPF_CGROUP_INET_SOCK_CREATE)); + RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_INET_CREATE_PROG_PATH, + cg_fd, BPF_CGROUP_INET_SOCK_CREATE)); + } + + 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_GETSOCKOPT_PROG_PATH, + cg_fd, BPF_CGROUP_GETSOCKOPT)); + RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_SETSOCKOPT_PROG_PATH, + cg_fd, BPF_CGROUP_SETSOCKOPT)); + RETURN_IF_NOT_OK(attachProgramToCgroup(CGROUP_INET_RELEASE_PROG_PATH, + cg_fd, BPF_CGROUP_INET_SOCK_RELEASE)); + } } if (bpf::isAtLeastKernelVersion(4, 19, 0)) { @@ -131,6 +154,20 @@ static Status initPrograms(const char* cg2_path) { if (bpf::queryProgram(cg_fd, BPF_CGROUP_INET6_BIND) <= 0) abort(); } + 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_GETSOCKOPT) <= 0) abort(); + if (bpf::queryProgram(cg_fd, BPF_CGROUP_SETSOCKOPT) <= 0) abort(); + if (bpf::queryProgram(cg_fd, BPF_CGROUP_INET_SOCK_RELEASE) <= 0) abort(); + } + } + return netdutils::status::ok; } diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 6a86905f09..be1d3c7c7c 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -113,11 +113,20 @@ import static android.system.OsConstants.F_OK; import static android.system.OsConstants.IPPROTO_TCP; import static android.system.OsConstants.IPPROTO_UDP; +import static com.android.net.module.util.BpfUtils.BPF_CGROUP_GETSOCKOPT; import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_BIND; +import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET4_CONNECT; import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_BIND; +import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET6_CONNECT; import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_EGRESS; import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_INGRESS; import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_SOCK_CREATE; +import static com.android.net.module.util.BpfUtils.BPF_CGROUP_INET_SOCK_RELEASE; +import static com.android.net.module.util.BpfUtils.BPF_CGROUP_SETSOCKOPT; +import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP4_RECVMSG; +import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP4_SENDMSG; +import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP6_RECVMSG; +import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP6_SENDMSG; import static com.android.net.module.util.NetworkMonitorUtils.isPrivateDnsValidationRequired; import static com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf; import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermission; @@ -3604,12 +3613,37 @@ public class ConnectivityService extends IConnectivityManager.Stub pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_INGRESS)); pw.print("CGROUP_INET_EGRESS: "); pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_EGRESS)); + pw.print("CGROUP_INET_SOCK_CREATE: "); pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_SOCK_CREATE)); + pw.print("CGROUP_INET4_BIND: "); pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET4_BIND)); pw.print("CGROUP_INET6_BIND: "); pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET6_BIND)); + + pw.print("CGROUP_INET4_CONNECT: "); + pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET4_CONNECT)); + pw.print("CGROUP_INET6_CONNECT: "); + pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET6_CONNECT)); + + pw.print("CGROUP_UDP4_SENDMSG: "); + pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP4_SENDMSG)); + pw.print("CGROUP_UDP6_SENDMSG: "); + pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP6_SENDMSG)); + + pw.print("CGROUP_UDP4_RECVMSG: "); + pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP4_RECVMSG)); + pw.print("CGROUP_UDP6_RECVMSG: "); + pw.println(mDeps.getBpfProgramId(BPF_CGROUP_UDP6_RECVMSG)); + + pw.print("CGROUP_GETSOCKOPT: "); + pw.println(mDeps.getBpfProgramId(BPF_CGROUP_GETSOCKOPT)); + pw.print("CGROUP_SETSOCKOPT: "); + pw.println(mDeps.getBpfProgramId(BPF_CGROUP_SETSOCKOPT)); + + pw.print("CGROUP_INET_SOCK_RELEASE: "); + pw.println(mDeps.getBpfProgramId(BPF_CGROUP_INET_SOCK_RELEASE)); } catch (IOException e) { pw.println(" IOException"); } diff --git a/staticlibs/device/com/android/net/module/util/BpfUtils.java b/staticlibs/device/com/android/net/module/util/BpfUtils.java index cdd6fd7665..a41eeba1e2 100644 --- a/staticlibs/device/com/android/net/module/util/BpfUtils.java +++ b/staticlibs/device/com/android/net/module/util/BpfUtils.java @@ -39,6 +39,15 @@ public class BpfUtils { public static final int BPF_CGROUP_INET_SOCK_CREATE = 2; public static final int BPF_CGROUP_INET4_BIND = 8; public static final int BPF_CGROUP_INET6_BIND = 9; + public static final int BPF_CGROUP_INET4_CONNECT = 10; + public static final int BPF_CGROUP_INET6_CONNECT = 11; + public static final int BPF_CGROUP_UDP4_SENDMSG = 14; + public static final int BPF_CGROUP_UDP6_SENDMSG = 15; + public static final int BPF_CGROUP_UDP4_RECVMSG = 19; + public static final int BPF_CGROUP_UDP6_RECVMSG = 20; + public static final int BPF_CGROUP_GETSOCKOPT = 21; + public static final int BPF_CGROUP_SETSOCKOPT = 22; + public static final int BPF_CGROUP_INET_SOCK_RELEASE = 34; // Note: This is only guaranteed to be accurate on U+ devices. It is likely to be accurate // on T+ devices as well, but this is not guaranteed. diff --git a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h index 9bd6470fad..e11a9e2751 100644 --- a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h +++ b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h @@ -140,6 +140,7 @@ struct kver_uint { unsigned int kver; }; #define KVER_5_4 KVER(5, 4, 0) #define KVER_5_8 KVER(5, 8, 0) #define KVER_5_9 KVER(5, 9, 0) +#define KVER_5_10 KVER(5, 10, 0) #define KVER_5_15 KVER(5, 15, 0) #define KVER_6_1 KVER(6, 1, 0) #define KVER_6_6 KVER(6, 6, 0) diff --git a/tests/mts/bpf_existence_test.cpp b/tests/mts/bpf_existence_test.cpp index e212e7de1a..3f0f3e9e4b 100644 --- a/tests/mts/bpf_existence_test.cpp +++ b/tests/mts/bpf_existence_test.cpp @@ -145,6 +145,23 @@ static const set MAINLINE_FOR_U_5_10_PLUS = { NETD "map_netd_packet_trace_ringbuf", }; +// 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", + NETD "prog_netd_getsockopt_prog", + NETD "prog_netd_setsockopt_prog", + NETD "prog_netd_cgroupsockrelease_inet_release", +}; + static void addAll(set& a, const set& b) { a.insert(b.begin(), b.end()); } @@ -192,6 +209,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); for (const auto& file : mustExist) { EXPECT_EQ(0, access(file.c_str(), R_OK)) << file << " does not exist";