bpfloader: don't depend on symtab ordering to find function name
readCodeSections implicitly assumes that a function's name will be the
first symbol in its section to appear in the symbol table, but this is
not guaranteed. In particular, when compiling with -g the section name
can appear before it, resulting in a failure to find the bpf_prog_def
information for that section's program.
Add a check for the STT_FUNC symbol type to narrow our search to the
function name symbol we actually want.
Also, add a test to check that a program with a minimum kernel version
of infinity will not be loaded, to verify that bpfloader successfully
finds bpf_prog_def information.
Test: boot & confirm progs all have correct owners & permissions
Test: build time_in_state.c with -g and confirm owner & permissions
set correctly
Test: libbpf_load_test now passes iff this fix is applied
Signed-off-by: Connor O'Brien <connoro@google.com>
Change-Id: I31db0c50d3adeed86ee5810b1a0fb972f56fdb47
diff --git a/libbpf_android/Loader.cpp b/libbpf_android/Loader.cpp
index cad5950..eb48cd0 100644
--- a/libbpf_android/Loader.cpp
+++ b/libbpf_android/Loader.cpp
@@ -356,7 +356,8 @@
return 0;
}
-static int getSectionSymNames(ifstream& elfFile, const string& sectionName, vector<string>& names) {
+static int getSectionSymNames(ifstream& elfFile, const string& sectionName, vector<string>& names,
+ optional<unsigned> symbolType = std::nullopt) {
int ret;
string name;
vector<Elf64_Sym> symtab;
@@ -387,6 +388,8 @@
}
for (int i = 0; i < (int)symtab.size(); i++) {
+ if (symbolType.has_value() && ELF_ST_TYPE(symtab[i].st_info) != symbolType) continue;
+
if (symtab[i].st_shndx == sec_idx) {
string s;
ret = getSymName(elfFile, symtab[i].st_name, s);
@@ -437,7 +440,7 @@
ALOGD("Loaded code section %d (%s)\n", i, name.c_str());
vector<string> csSymNames;
- ret = getSectionSymNames(elfFile, oldName, csSymNames);
+ ret = getSectionSymNames(elfFile, oldName, csSymNames, STT_FUNC);
if (ret || !csSymNames.size()) return ret;
for (size_t i = 0; i < progDefNames.size(); ++i) {
if (!progDefNames[i].compare(csSymNames[0] + "_def")) {