Merge changes I163e21fd,I1b0943d3,I3af8e7f1 into main
* changes: netbpfload: remove support for limiting program types netbpfload: remove non-network program types netbpfload: add Android.bp file
This commit is contained in:
42
netbpfload/Android.bp
Normal file
42
netbpfload/Android.bp
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2023 The Android Open Source Project
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
|
||||||
|
cc_binary {
|
||||||
|
name: "netbpfload",
|
||||||
|
|
||||||
|
defaults: ["bpf_defaults"],
|
||||||
|
cflags: [
|
||||||
|
"-Wall",
|
||||||
|
"-Werror",
|
||||||
|
"-Wthread-safety",
|
||||||
|
],
|
||||||
|
sanitize: {
|
||||||
|
integer_overflow: true,
|
||||||
|
},
|
||||||
|
|
||||||
|
header_libs: ["bpf_headers"],
|
||||||
|
shared_libs: [
|
||||||
|
"libbase",
|
||||||
|
"libcutils",
|
||||||
|
"liblog",
|
||||||
|
],
|
||||||
|
srcs: [
|
||||||
|
"loader.cpp",
|
||||||
|
"NetBpfLoad.cpp",
|
||||||
|
],
|
||||||
|
|
||||||
|
init_rc: ["netbpfload.rc"],
|
||||||
|
}
|
||||||
@@ -44,12 +44,11 @@
|
|||||||
#include <android-base/stringprintf.h>
|
#include <android-base/stringprintf.h>
|
||||||
#include <android-base/strings.h>
|
#include <android-base/strings.h>
|
||||||
#include <android-base/unique_fd.h>
|
#include <android-base/unique_fd.h>
|
||||||
#include <libbpf_android.h>
|
|
||||||
#include <log/log.h>
|
#include <log/log.h>
|
||||||
#include <netdutils/Misc.h>
|
|
||||||
#include <netdutils/Slice.h>
|
|
||||||
#include "BpfSyscallWrappers.h"
|
#include "BpfSyscallWrappers.h"
|
||||||
#include "bpf/BpfUtils.h"
|
#include "bpf/BpfUtils.h"
|
||||||
|
#include "loader.h"
|
||||||
|
|
||||||
using android::base::EndsWith;
|
using android::base::EndsWith;
|
||||||
using android::bpf::domain;
|
using android::bpf::domain;
|
||||||
@@ -73,26 +72,6 @@ constexpr unsigned long long kTetheringApexDomainBitmask =
|
|||||||
domainToBitmask(domain::netd_readonly) |
|
domainToBitmask(domain::netd_readonly) |
|
||||||
domainToBitmask(domain::netd_shared);
|
domainToBitmask(domain::netd_shared);
|
||||||
|
|
||||||
// Programs shipped inside the tethering apex should be limited to networking stuff,
|
|
||||||
// as KPROBE, PERF_EVENT, TRACEPOINT are dangerous to use from mainline updatable code,
|
|
||||||
// since they are less stable abi/api and may conflict with platform uses of bpf.
|
|
||||||
constexpr bpf_prog_type kTetheringApexAllowedProgTypes[] = {
|
|
||||||
BPF_PROG_TYPE_CGROUP_SKB,
|
|
||||||
BPF_PROG_TYPE_CGROUP_SOCK,
|
|
||||||
BPF_PROG_TYPE_CGROUP_SOCKOPT,
|
|
||||||
BPF_PROG_TYPE_CGROUP_SOCK_ADDR,
|
|
||||||
BPF_PROG_TYPE_CGROUP_SYSCTL,
|
|
||||||
BPF_PROG_TYPE_LWT_IN,
|
|
||||||
BPF_PROG_TYPE_LWT_OUT,
|
|
||||||
BPF_PROG_TYPE_LWT_SEG6LOCAL,
|
|
||||||
BPF_PROG_TYPE_LWT_XMIT,
|
|
||||||
BPF_PROG_TYPE_SCHED_ACT,
|
|
||||||
BPF_PROG_TYPE_SCHED_CLS,
|
|
||||||
BPF_PROG_TYPE_SOCKET_FILTER,
|
|
||||||
BPF_PROG_TYPE_SOCK_OPS,
|
|
||||||
BPF_PROG_TYPE_XDP,
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const android::bpf::Location locations[] = {
|
const android::bpf::Location locations[] = {
|
||||||
// S+ Tethering mainline module (network_stack): tether offload
|
// S+ Tethering mainline module (network_stack): tether offload
|
||||||
@@ -100,8 +79,6 @@ const android::bpf::Location locations[] = {
|
|||||||
.dir = "/apex/com.android.tethering/etc/bpf/",
|
.dir = "/apex/com.android.tethering/etc/bpf/",
|
||||||
.prefix = "tethering/",
|
.prefix = "tethering/",
|
||||||
.allowedDomainBitmask = kTetheringApexDomainBitmask,
|
.allowedDomainBitmask = kTetheringApexDomainBitmask,
|
||||||
.allowedProgTypes = kTetheringApexAllowedProgTypes,
|
|
||||||
.allowedProgTypesLength = arraysize(kTetheringApexAllowedProgTypes),
|
|
||||||
},
|
},
|
||||||
// T+ Tethering mainline module (shared with netd & system server)
|
// T+ Tethering mainline module (shared with netd & system server)
|
||||||
// netutils_wrapper (for iptables xt_bpf) has access to programs
|
// netutils_wrapper (for iptables xt_bpf) has access to programs
|
||||||
@@ -109,8 +86,6 @@ const android::bpf::Location locations[] = {
|
|||||||
.dir = "/apex/com.android.tethering/etc/bpf/netd_shared/",
|
.dir = "/apex/com.android.tethering/etc/bpf/netd_shared/",
|
||||||
.prefix = "netd_shared/",
|
.prefix = "netd_shared/",
|
||||||
.allowedDomainBitmask = kTetheringApexDomainBitmask,
|
.allowedDomainBitmask = kTetheringApexDomainBitmask,
|
||||||
.allowedProgTypes = kTetheringApexAllowedProgTypes,
|
|
||||||
.allowedProgTypesLength = arraysize(kTetheringApexAllowedProgTypes),
|
|
||||||
},
|
},
|
||||||
// T+ Tethering mainline module (shared with netd & system server)
|
// T+ Tethering mainline module (shared with netd & system server)
|
||||||
// netutils_wrapper has no access, netd has read only access
|
// netutils_wrapper has no access, netd has read only access
|
||||||
@@ -118,24 +93,18 @@ const android::bpf::Location locations[] = {
|
|||||||
.dir = "/apex/com.android.tethering/etc/bpf/netd_readonly/",
|
.dir = "/apex/com.android.tethering/etc/bpf/netd_readonly/",
|
||||||
.prefix = "netd_readonly/",
|
.prefix = "netd_readonly/",
|
||||||
.allowedDomainBitmask = kTetheringApexDomainBitmask,
|
.allowedDomainBitmask = kTetheringApexDomainBitmask,
|
||||||
.allowedProgTypes = kTetheringApexAllowedProgTypes,
|
|
||||||
.allowedProgTypesLength = arraysize(kTetheringApexAllowedProgTypes),
|
|
||||||
},
|
},
|
||||||
// T+ Tethering mainline module (shared with system server)
|
// T+ Tethering mainline module (shared with system server)
|
||||||
{
|
{
|
||||||
.dir = "/apex/com.android.tethering/etc/bpf/net_shared/",
|
.dir = "/apex/com.android.tethering/etc/bpf/net_shared/",
|
||||||
.prefix = "net_shared/",
|
.prefix = "net_shared/",
|
||||||
.allowedDomainBitmask = kTetheringApexDomainBitmask,
|
.allowedDomainBitmask = kTetheringApexDomainBitmask,
|
||||||
.allowedProgTypes = kTetheringApexAllowedProgTypes,
|
|
||||||
.allowedProgTypesLength = arraysize(kTetheringApexAllowedProgTypes),
|
|
||||||
},
|
},
|
||||||
// T+ Tethering mainline module (not shared, just network_stack)
|
// T+ Tethering mainline module (not shared, just network_stack)
|
||||||
{
|
{
|
||||||
.dir = "/apex/com.android.tethering/etc/bpf/net_private/",
|
.dir = "/apex/com.android.tethering/etc/bpf/net_private/",
|
||||||
.prefix = "net_private/",
|
.prefix = "net_private/",
|
||||||
.allowedDomainBitmask = kTetheringApexDomainBitmask,
|
.allowedDomainBitmask = kTetheringApexDomainBitmask,
|
||||||
.allowedProgTypes = kTetheringApexAllowedProgTypes,
|
|
||||||
.allowedProgTypesLength = arraysize(kTetheringApexAllowedProgTypes),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
#include "BpfSyscallWrappers.h"
|
#include "BpfSyscallWrappers.h"
|
||||||
#include "bpf/BpfUtils.h"
|
#include "bpf/BpfUtils.h"
|
||||||
#include "bpf/bpf_map_def.h"
|
#include "bpf/bpf_map_def.h"
|
||||||
#include "include/libbpf_android.h"
|
#include "loader.h"
|
||||||
|
|
||||||
#if BPFLOADER_VERSION < COMPILE_FOR_BPFLOADER_VERSION
|
#if BPFLOADER_VERSION < COMPILE_FOR_BPFLOADER_VERSION
|
||||||
#error "BPFLOADER_VERSION is less than COMPILE_FOR_BPFLOADER_VERSION"
|
#error "BPFLOADER_VERSION is less than COMPILE_FOR_BPFLOADER_VERSION"
|
||||||
@@ -178,6 +178,10 @@ typedef struct {
|
|||||||
*
|
*
|
||||||
* However, be aware that you should not be directly using the SECTION() macro.
|
* However, be aware that you should not be directly using the SECTION() macro.
|
||||||
* Instead use the DEFINE_(BPF|XDP)_(PROG|MAP)... & LICENSE/CRITICAL macros.
|
* Instead use the DEFINE_(BPF|XDP)_(PROG|MAP)... & LICENSE/CRITICAL macros.
|
||||||
|
*
|
||||||
|
* Programs shipped inside the tethering apex should be limited to networking stuff,
|
||||||
|
* as KPROBE, PERF_EVENT, TRACEPOINT are dangerous to use from mainline updatable code,
|
||||||
|
* since they are less stable abi/api and may conflict with platform uses of bpf.
|
||||||
*/
|
*/
|
||||||
sectionType sectionNameTypes[] = {
|
sectionType sectionNameTypes[] = {
|
||||||
{"bind4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_BIND},
|
{"bind4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_INET4_BIND},
|
||||||
@@ -189,13 +193,10 @@ sectionType sectionNameTypes[] = {
|
|||||||
{"egress/", BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_EGRESS},
|
{"egress/", BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_EGRESS},
|
||||||
{"getsockopt/", BPF_PROG_TYPE_CGROUP_SOCKOPT, BPF_CGROUP_GETSOCKOPT},
|
{"getsockopt/", BPF_PROG_TYPE_CGROUP_SOCKOPT, BPF_CGROUP_GETSOCKOPT},
|
||||||
{"ingress/", BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_INGRESS},
|
{"ingress/", BPF_PROG_TYPE_CGROUP_SKB, BPF_CGROUP_INET_INGRESS},
|
||||||
{"kprobe/", BPF_PROG_TYPE_KPROBE, BPF_ATTACH_TYPE_UNSPEC},
|
|
||||||
{"kretprobe/", BPF_PROG_TYPE_KPROBE, BPF_ATTACH_TYPE_UNSPEC},
|
|
||||||
{"lwt_in/", BPF_PROG_TYPE_LWT_IN, BPF_ATTACH_TYPE_UNSPEC},
|
{"lwt_in/", BPF_PROG_TYPE_LWT_IN, BPF_ATTACH_TYPE_UNSPEC},
|
||||||
{"lwt_out/", BPF_PROG_TYPE_LWT_OUT, 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_seg6local/", BPF_PROG_TYPE_LWT_SEG6LOCAL, BPF_ATTACH_TYPE_UNSPEC},
|
||||||
{"lwt_xmit/", BPF_PROG_TYPE_LWT_XMIT, BPF_ATTACH_TYPE_UNSPEC},
|
{"lwt_xmit/", BPF_PROG_TYPE_LWT_XMIT, BPF_ATTACH_TYPE_UNSPEC},
|
||||||
{"perf_event/", BPF_PROG_TYPE_PERF_EVENT, BPF_ATTACH_TYPE_UNSPEC},
|
|
||||||
{"postbind4/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET4_POST_BIND},
|
{"postbind4/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET4_POST_BIND},
|
||||||
{"postbind6/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET6_POST_BIND},
|
{"postbind6/", BPF_PROG_TYPE_CGROUP_SOCK, BPF_CGROUP_INET6_POST_BIND},
|
||||||
{"recvmsg4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_UDP4_RECVMSG},
|
{"recvmsg4/", BPF_PROG_TYPE_CGROUP_SOCK_ADDR, BPF_CGROUP_UDP4_RECVMSG},
|
||||||
@@ -208,9 +209,6 @@ sectionType sectionNameTypes[] = {
|
|||||||
{"skfilter/", BPF_PROG_TYPE_SOCKET_FILTER, BPF_ATTACH_TYPE_UNSPEC},
|
{"skfilter/", BPF_PROG_TYPE_SOCKET_FILTER, BPF_ATTACH_TYPE_UNSPEC},
|
||||||
{"sockops/", BPF_PROG_TYPE_SOCK_OPS, BPF_CGROUP_SOCK_OPS},
|
{"sockops/", BPF_PROG_TYPE_SOCK_OPS, BPF_CGROUP_SOCK_OPS},
|
||||||
{"sysctl", BPF_PROG_TYPE_CGROUP_SYSCTL, BPF_CGROUP_SYSCTL},
|
{"sysctl", BPF_PROG_TYPE_CGROUP_SYSCTL, BPF_CGROUP_SYSCTL},
|
||||||
{"tracepoint/", BPF_PROG_TYPE_TRACEPOINT, BPF_ATTACH_TYPE_UNSPEC},
|
|
||||||
{"uprobe/", BPF_PROG_TYPE_KPROBE, BPF_ATTACH_TYPE_UNSPEC},
|
|
||||||
{"uretprobe/", BPF_PROG_TYPE_KPROBE, BPF_ATTACH_TYPE_UNSPEC},
|
|
||||||
{"xdp/", BPF_PROG_TYPE_XDP, BPF_ATTACH_TYPE_UNSPEC},
|
{"xdp/", BPF_PROG_TYPE_XDP, BPF_ATTACH_TYPE_UNSPEC},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -393,19 +391,10 @@ static int readSymTab(ifstream& elfFile, int sort, vector<Elf64_Sym>& data) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum bpf_prog_type getFuseProgType() {
|
|
||||||
int result = BPF_PROG_TYPE_UNSPEC;
|
|
||||||
ifstream("/sys/fs/fuse/bpf_prog_type_fuse") >> result;
|
|
||||||
return static_cast<bpf_prog_type>(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum bpf_prog_type getSectionType(string& name) {
|
static enum bpf_prog_type getSectionType(string& name) {
|
||||||
for (auto& snt : sectionNameTypes)
|
for (auto& snt : sectionNameTypes)
|
||||||
if (StartsWith(name, snt.name)) return snt.type;
|
if (StartsWith(name, snt.name)) return snt.type;
|
||||||
|
|
||||||
// TODO Remove this code when fuse-bpf is upstream and this BPF_PROG_TYPE_FUSE is fixed
|
|
||||||
if (StartsWith(name, "fuse/")) return getFuseProgType();
|
|
||||||
|
|
||||||
return BPF_PROG_TYPE_UNSPEC;
|
return BPF_PROG_TYPE_UNSPEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,6 +404,7 @@ static enum bpf_attach_type getExpectedAttachType(string& name) {
|
|||||||
return BPF_ATTACH_TYPE_UNSPEC;
|
return BPF_ATTACH_TYPE_UNSPEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
static string getSectionName(enum bpf_prog_type type)
|
static string getSectionName(enum bpf_prog_type type)
|
||||||
{
|
{
|
||||||
for (auto& snt : sectionNameTypes)
|
for (auto& snt : sectionNameTypes)
|
||||||
@@ -423,6 +413,7 @@ static string getSectionName(enum bpf_prog_type type)
|
|||||||
|
|
||||||
return "UNKNOWN SECTION NAME " + std::to_string(type);
|
return "UNKNOWN SECTION NAME " + std::to_string(type);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
static int readProgDefs(ifstream& elfFile, vector<struct bpf_prog_def>& pd,
|
static int readProgDefs(ifstream& elfFile, vector<struct bpf_prog_def>& pd,
|
||||||
size_t sizeOfBpfProgDef) {
|
size_t sizeOfBpfProgDef) {
|
||||||
@@ -502,22 +493,8 @@ static int getSectionSymNames(ifstream& elfFile, const string& sectionName, vect
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsAllowed(bpf_prog_type type, const bpf_prog_type* allowed, size_t numAllowed) {
|
|
||||||
if (allowed == nullptr) return true;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < numAllowed; i++) {
|
|
||||||
if (allowed[i] == BPF_PROG_TYPE_UNSPEC) {
|
|
||||||
if (type == getFuseProgType()) return true;
|
|
||||||
} else if (type == allowed[i])
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read a section by its index - for ex to get sec hdr strtab blob */
|
/* Read a section by its index - for ex to get sec hdr strtab blob */
|
||||||
static int readCodeSections(ifstream& elfFile, vector<codeSection>& cs, size_t sizeOfBpfProgDef,
|
static int readCodeSections(ifstream& elfFile, vector<codeSection>& cs, size_t sizeOfBpfProgDef) {
|
||||||
const bpf_prog_type* allowed, size_t numAllowed) {
|
|
||||||
vector<Elf64_Shdr> shTable;
|
vector<Elf64_Shdr> shTable;
|
||||||
int entries, ret = 0;
|
int entries, ret = 0;
|
||||||
|
|
||||||
@@ -544,11 +521,6 @@ static int readCodeSections(ifstream& elfFile, vector<codeSection>& cs, size_t s
|
|||||||
|
|
||||||
if (ptype == BPF_PROG_TYPE_UNSPEC) continue;
|
if (ptype == BPF_PROG_TYPE_UNSPEC) continue;
|
||||||
|
|
||||||
if (!IsAllowed(ptype, allowed, numAllowed)) {
|
|
||||||
ALOGE("Program type %s not permitted here", getSectionName(ptype).c_str());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This must be done before '/' is replaced with '_'.
|
// This must be done before '/' is replaced with '_'.
|
||||||
cs_temp.expected_attach_type = getExpectedAttachType(name);
|
cs_temp.expected_attach_type = getExpectedAttachType(name);
|
||||||
|
|
||||||
@@ -1210,8 +1182,7 @@ int loadProg(const char* elfPath, bool* isCritical, const Location& location) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = readCodeSections(elfFile, cs, sizeOfBpfProgDef, location.allowedProgTypes,
|
ret = readCodeSections(elfFile, cs, sizeOfBpfProgDef);
|
||||||
location.allowedProgTypesLength);
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ALOGE("Couldn't read all code sections in %s", elfPath);
|
ALOGE("Couldn't read all code sections in %s", elfPath);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -76,8 +76,6 @@ struct Location {
|
|||||||
const char* const dir = "";
|
const char* const dir = "";
|
||||||
const char* const prefix = "";
|
const char* const prefix = "";
|
||||||
unsigned long long allowedDomainBitmask = 0;
|
unsigned long long allowedDomainBitmask = 0;
|
||||||
const bpf_prog_type* allowedProgTypes = nullptr;
|
|
||||||
size_t allowedProgTypesLength = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// BPF loader implementation. Loads an eBPF ELF object
|
// BPF loader implementation. Loads an eBPF ELF object
|
||||||
|
|||||||
Reference in New Issue
Block a user