summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libbpf_android/Loader.cpp129
-rw-r--r--progs/include/bpf_helpers.h8
-rw-r--r--progs/include/bpf_map_def.h5
3 files changed, 97 insertions, 45 deletions
diff --git a/libbpf_android/Loader.cpp b/libbpf_android/Loader.cpp
index 1c27f9e..8f139a3 100644
--- a/libbpf_android/Loader.cpp
+++ b/libbpf_android/Loader.cpp
@@ -35,6 +35,7 @@
#include <cstdlib>
#include <fstream>
#include <iostream>
+#include <optional>
#include <string>
#include <vector>
@@ -51,6 +52,7 @@ using android::base::StartsWith;
using android::base::unique_fd;
using std::ifstream;
using std::ios;
+using std::optional;
using std::string;
using std::vector;
@@ -86,6 +88,7 @@ typedef struct {
string name;
vector<char> data;
vector<char> rel_data;
+ optional<struct bpf_prog_def> prog_def;
unique_fd prog_fd; /* fd after loading */
} codeSection;
@@ -272,6 +275,59 @@ static bool isRelSection(codeSection& cs, string& name) {
return false;
}
+static int readProgDefs(ifstream& elfFile, vector<struct bpf_prog_def>& pd) {
+ vector<char> pdData;
+ int ret = readSectionByName("progs", elfFile, pdData);
+ if (ret == -2) return 0;
+ if (ret) return ret;
+
+ pd.resize(pdData.size() / sizeof(struct bpf_prog_def));
+ memcpy(pd.data(), pdData.data(), pdData.size());
+ return 0;
+}
+
+static int getSectionSymNames(ifstream& elfFile, const string& sectionName, vector<string>& names) {
+ int ret;
+ string name;
+ vector<Elf64_Sym> symtab;
+ vector<Elf64_Shdr> shTable;
+
+ ret = readSymTab(elfFile, 1 /* sort */, symtab);
+ if (ret) return ret;
+
+ /* Get index of section */
+ ret = readSectionHeadersAll(elfFile, shTable);
+ if (ret) return ret;
+
+ int sec_idx = -1;
+ for (int i = 0; i < (int)shTable.size(); i++) {
+ ret = getSymName(elfFile, shTable[i].sh_name, name);
+ if (ret) return ret;
+
+ if (!name.compare(sectionName)) {
+ sec_idx = i;
+ break;
+ }
+ }
+
+ /* No section found with matching name*/
+ if (sec_idx == -1) {
+ ALOGE("No %s section could be found in elf object\n", sectionName.c_str());
+ return -1;
+ }
+
+ for (int i = 0; i < (int)symtab.size(); i++) {
+ if (symtab[i].st_shndx == sec_idx) {
+ string s;
+ ret = getSymName(elfFile, symtab[i].st_name, s);
+ if (ret) return ret;
+ names.push_back(s);
+ }
+ }
+
+ return 0;
+}
+
/* Read a section by its index - for ex to get sec hdr strtab blob */
static int readCodeSections(ifstream& elfFile, vector<codeSection>& cs) {
vector<Elf64_Shdr> shTable;
@@ -281,6 +337,13 @@ static int readCodeSections(ifstream& elfFile, vector<codeSection>& cs) {
if (ret) return ret;
entries = shTable.size();
+ vector<struct bpf_prog_def> pd;
+ ret = readProgDefs(elfFile, pd);
+ if (ret) return ret;
+ vector<string> progDefNames;
+ ret = getSectionSymNames(elfFile, "progs", progDefNames);
+ if (!pd.empty() && ret) return ret;
+
for (int i = 0; i < entries; i++) {
string name;
codeSection cs_temp;
@@ -291,6 +354,7 @@ static int readCodeSections(ifstream& elfFile, vector<codeSection>& cs) {
enum bpf_prog_type ptype = getSectionType(name);
if (ptype != BPF_PROG_TYPE_UNSPEC) {
+ string oldName = name;
deslash(name);
cs_temp.type = ptype;
cs_temp.name = name;
@@ -298,6 +362,16 @@ static int readCodeSections(ifstream& elfFile, vector<codeSection>& cs) {
ret = readSectionByIdx(elfFile, i, cs_temp.data);
if (ret) return ret;
ALOGD("Loaded code section %d (%s)\n", i, name.c_str());
+
+ vector<string> csSymNames;
+ ret = getSectionSymNames(elfFile, oldName, csSymNames);
+ if (ret || !csSymNames.size()) return ret;
+ for (size_t i = 0; i < progDefNames.size(); ++i) {
+ if (!progDefNames[i].compare(csSymNames[0] + "_def")) {
+ cs_temp.prog_def = pd[i];
+ break;
+ }
+ }
}
/* Check for rel section */
@@ -332,48 +406,6 @@ static int getSymNameByIdx(ifstream& elfFile, int index, string& name) {
return getSymName(elfFile, symtab[index].st_name, name);
}
-static int getMapNames(ifstream& elfFile, vector<string>& names) {
- int ret;
- string mapName;
- vector<Elf64_Sym> symtab;
- vector<Elf64_Shdr> shTable;
-
- ret = readSymTab(elfFile, 1 /* sort */, symtab);
- if (ret) return ret;
-
- /* Get index of maps section */
- ret = readSectionHeadersAll(elfFile, shTable);
- if (ret) return ret;
-
- int maps_idx = -1;
- for (int i = 0; i < (int)shTable.size(); i++) {
- ret = getSymName(elfFile, shTable[i].sh_name, mapName);
- if (ret) return ret;
-
- if (!mapName.compare("maps")) {
- maps_idx = i;
- break;
- }
- }
-
- /* No maps found */
- if (maps_idx == -1) {
- ALOGE("No maps could be found in elf object\n");
- return -1;
- }
-
- for (int i = 0; i < (int)symtab.size(); i++) {
- if (symtab[i].st_shndx == maps_idx) {
- string s;
- ret = getSymName(elfFile, symtab[i].st_name, s);
- if (ret) return ret;
- names.push_back(s);
- }
- }
-
- return 0;
-}
-
static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>& mapFds) {
int ret;
vector<char> mdData;
@@ -387,7 +419,7 @@ static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>&
md.resize(mdData.size() / sizeof(struct bpf_map_def));
memcpy(md.data(), mdData.data(), mdData.size());
- ret = getMapNames(elfFile, mapNames);
+ ret = getSectionSymNames(elfFile, "maps", mapNames);
if (ret) return ret;
for (int i = 0; i < (int)mapNames.size(); i++) {
@@ -473,7 +505,7 @@ static void applyRelo(void* insnsPtr, Elf64_Addr offset, int fd) {
static void applyMapRelo(ifstream& elfFile, vector<unique_fd> &mapFds, vector<codeSection>& cs) {
vector<string> mapNames;
- int ret = getMapNames(elfFile, mapNames);
+ int ret = getSectionSymNames(elfFile, "maps", mapNames);
if (ret) return;
for (int k = 0; k != (int)cs.size(); k++) {
@@ -539,7 +571,14 @@ static int loadCodeSections(const char* elfPath, vector<codeSection>& cs, const
if (!reuse) {
ret = bpf_obj_pin(fd, progPinLoc.c_str());
- if (ret < 0) return ret;
+ if (ret) return -errno;
+ if (cs[i].prog_def.has_value()) {
+ if (chown(progPinLoc.c_str(), (uid_t)cs[i].prog_def->uid,
+ (gid_t)cs[i].prog_def->gid)) {
+ return -errno;
+ }
+ }
+ if (chmod(progPinLoc.c_str(), 0440)) return -errno;
}
cs[i].prog_fd.reset(fd);
diff --git a/progs/include/bpf_helpers.h b/progs/include/bpf_helpers.h
index ac08649..605e9a4 100644
--- a/progs/include/bpf_helpers.h
+++ b/progs/include/bpf_helpers.h
@@ -94,3 +94,11 @@ static int (*bpf_trace_printk)(const char* fmt, int fmt_size, ...) = (void*) BPF
static unsigned long long (*bpf_get_current_pid_tgid)(void) = (void*) BPF_FUNC_get_current_pid_tgid;
static unsigned long long (*bpf_get_current_uid_gid)(void) = (void*) BPF_FUNC_get_current_uid_gid;
static unsigned long long (*bpf_get_smp_processor_id)(void) = (void*) BPF_FUNC_get_smp_processor_id;
+
+#define DEFINE_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
+ const struct bpf_prog_def SEC("progs") the_prog##_def = { \
+ .uid = (prog_uid), \
+ .gid = (prog_gid), \
+ }; \
+ SEC(SECTION_NAME) \
+ int the_prog
diff --git a/progs/include/bpf_map_def.h b/progs/include/bpf_map_def.h
index b233dc9..3aee332 100644
--- a/progs/include/bpf_map_def.h
+++ b/progs/include/bpf_map_def.h
@@ -67,3 +67,8 @@ struct bpf_map_def {
unsigned int gid; // gid_t
unsigned int mode; // mode_t
};
+
+struct bpf_prog_def {
+ unsigned int uid;
+ unsigned int gid;
+};