netbpfload: remove support for limiting program types

No need for this, as we simply only support network
program types in the first place.

Test: TreeHugger
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I163e21fd4d4089882cf37fc68bc4299003b514d7
This commit is contained in:
Maciej Żenczykowski
2023-10-08 23:35:00 -07:00
parent 02519f86ad
commit fcea70f840
3 changed files with 8 additions and 63 deletions

View File

@@ -72,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
@@ -99,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
@@ -108,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
@@ -117,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),
}, },
}; };

View File

@@ -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},
@@ -387,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;
} }
@@ -409,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)
@@ -417,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) {
@@ -496,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;
@@ -538,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);
@@ -1204,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;

View File

@@ -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