summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej Żenczykowski <maze@google.com>2020-06-15 13:09:30 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-06-15 13:09:30 +0000
commit89b297968b502f8b4be025fe32fa4d66bedf455c (patch)
tree09b8c2c18a6a3cbc7e271aea65bd4805de92c903
parent0703b717b134df84523587e175c7f5ef8eb82b36 (diff)
parent45f5ffd167b6fd172866fc8f6e9fa0895fbd6528 (diff)
downloadbpf-89b297968b502f8b4be025fe32fa4d66bedf455c.tar.gz
Warn loudly and do not set bpf.progs_loaded property on critical bpf load failure. am: 45f5ffd167
Original change: https://googleplex-android-review.googlesource.com/c/platform/system/bpf/+/11859851 Change-Id: Ie46889d9d024b7d0abdd830cb0d59c3e698f9c2a
-rw-r--r--bpfloader/BpfLoader.cpp25
-rw-r--r--libbpf_android/BpfLoadTest.cpp4
-rw-r--r--libbpf_android/Loader.cpp10
-rw-r--r--libbpf_android/include/libbpf_android.h2
4 files changed, 30 insertions, 11 deletions
diff --git a/bpfloader/BpfLoader.cpp b/bpfloader/BpfLoader.cpp
index 9e348e5..e67c469 100644
--- a/bpfloader/BpfLoader.cpp
+++ b/bpfloader/BpfLoader.cpp
@@ -53,7 +53,8 @@ using std::string;
#define BPF_PROG_PATH "/system/etc/bpf/"
-void loadAllElfObjects(void) {
+int loadAllElfObjects(void) {
+ int retVal = 0;
DIR* dir;
struct dirent* ent;
@@ -64,21 +65,35 @@ void loadAllElfObjects(void) {
string progPath = BPF_PROG_PATH + s;
- int ret = android::bpf::loadProg(progPath.c_str());
- ALOGI("Attempted load object: %s, ret: %s", progPath.c_str(), std::strerror(-ret));
+ bool critical;
+ int ret = android::bpf::loadProg(progPath.c_str(), &critical);
+ if (ret) {
+ if (critical) retVal = ret;
+ ALOGE("Failed to load object: %s, ret: %s", progPath.c_str(), std::strerror(-ret));
+ } else {
+ ALOGI("Loaded object: %s", progPath.c_str());
+ }
}
closedir(dir);
}
+ return retVal;
}
int main() {
if (!android::bpf::isBpfSupported()) return 0;
// Load all ELF objects, create programs and maps, and pin them
- loadAllElfObjects();
+ if (loadAllElfObjects() != 0) {
+ ALOGE("=== CRITICAL FAILURE LOADING BPF PROGRAMS ===");
+ ALOGE("If this triggers reliably, you're probably missing kernel options or patches.");
+ ALOGE("If this triggers randomly, you might be hitting some memory allocation problems or "
+ "startup script race.");
+ ALOGE("--- DO NOT EXPECT SYSTEM TO BOOT SUCCESSFULLY ---");
+ return 2;
+ }
if (android::base::SetProperty("bpf.progs_loaded", "1") == false) {
- ALOGE("Failed to set bpf.progs_loaded property\n");
+ ALOGE("Failed to set bpf.progs_loaded property");
return 1;
}
diff --git a/libbpf_android/BpfLoadTest.cpp b/libbpf_android/BpfLoadTest.cpp
index 349e997..b384c11 100644
--- a/libbpf_android/BpfLoadTest.cpp
+++ b/libbpf_android/BpfLoadTest.cpp
@@ -43,7 +43,9 @@ class BpfLoadTest : public testing::Test {
unlink(tp_prog_path);
unlink(tp_map_path);
- EXPECT_EQ(android::bpf::loadProg("/system/etc/bpf/bpf_load_tp_prog.o"), 0);
+ bool critical = true;
+ EXPECT_EQ(android::bpf::loadProg("/system/etc/bpf/bpf_load_tp_prog.o", &critical), 0);
+ EXPECT_EQ(false, critical);
mProgFd = bpf_obj_get(tp_prog_path);
EXPECT_GT(mProgFd, 0);
diff --git a/libbpf_android/Loader.cpp b/libbpf_android/Loader.cpp
index 9f57ce6..8f5318d 100644
--- a/libbpf_android/Loader.cpp
+++ b/libbpf_android/Loader.cpp
@@ -606,19 +606,21 @@ static int loadCodeSections(const char* elfPath, vector<codeSection>& cs, const
return 0;
}
-int loadProg(const char* elfPath) {
+int loadProg(const char* elfPath, bool* isCritical) {
vector<char> license;
vector<char> critical;
vector<codeSection> cs;
vector<unique_fd> mapFds;
- bool is_critical;
int ret;
+ if (!isCritical) return -1;
+ *isCritical = false;
+
ifstream elfFile(elfPath, ios::in | ios::binary);
if (!elfFile.is_open()) return -1;
ret = readSectionByName("critical", elfFile, critical);
- is_critical = !ret;
+ *isCritical = !ret;
ret = readSectionByName("license", elfFile, license);
if (ret) {
@@ -626,7 +628,7 @@ int loadProg(const char* elfPath) {
return ret;
} else {
ALOGD("Loading %s%s ELF object %s with license %s\n",
- is_critical ? "critical for " : "optional", is_critical ? (char*)critical.data() : "",
+ *isCritical ? "critical for " : "optional", *isCritical ? (char*)critical.data() : "",
elfPath, (char*)license.data());
}
diff --git a/libbpf_android/include/libbpf_android.h b/libbpf_android/include/libbpf_android.h
index 0a01c85..3810d07 100644
--- a/libbpf_android/include/libbpf_android.h
+++ b/libbpf_android/include/libbpf_android.h
@@ -25,7 +25,7 @@ namespace android {
namespace bpf {
// BPF loader implementation. Loads an eBPF ELF object
-int loadProg(const char* elfpath);
+int loadProg(const char* elfPath, bool* isCritical);
// Wait for bpfloader to load BPF programs.
void waitForProgsLoaded();