diff options
-rw-r--r-- | libbpf_android/Loader.cpp | 129 | ||||
-rw-r--r-- | progs/include/bpf_helpers.h | 8 | ||||
-rw-r--r-- | progs/include/bpf_map_def.h | 5 |
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; +}; |