Adding service manager fuzzer. Android platform specific macros are added in access.cpp because of dependency on libselinux.
Steps to run:
On host :
m servicemanager_fuzzer && $ANDROID_HOST_OUT/fuzz/x86_64/servicemanager_fuzzer/servicemanager_fuzzer
On Device:
cd ${ANDROID_PRODUCT_OUT}
adb root
adb sync data
adb shell /data/fuzz/$(get_build_var TARGET_ARCH)/servicemanager_fuzzer/servicemanager_fuzzer
Test: atest servicemanager_test
Bug: 232439428
Change-Id: Ic20b7e842bcaa40762e612557a3d85bf009ae105
diff --git a/cmds/servicemanager/Access.cpp b/cmds/servicemanager/Access.cpp
index b7e520f..711038c 100644
--- a/cmds/servicemanager/Access.cpp
+++ b/cmds/servicemanager/Access.cpp
@@ -30,6 +30,7 @@
constexpr bool kIsVendor = false;
#endif
+#ifdef __ANDROID__
static std::string getPidcon(pid_t pid) {
android_errorWriteLog(0x534e4554, "121035042");
@@ -45,7 +46,6 @@
static struct selabel_handle* getSehandle() {
static struct selabel_handle* gSehandle = nullptr;
-
if (gSehandle != nullptr && selinux_status_updated()) {
selabel_close(gSehandle);
gSehandle = nullptr;
@@ -78,8 +78,10 @@
ad->tname->c_str());
return 0;
}
+#endif
Access::Access() {
+#ifdef __ANDROID__
union selinux_callback cb;
cb.func_audit = auditCallback;
@@ -91,6 +93,7 @@
CHECK(selinux_status_open(true /*fallback*/) >= 0);
CHECK(getcon(&mThisProcessContext) == 0);
+#endif
}
Access::~Access() {
@@ -98,6 +101,7 @@
}
Access::CallingContext Access::getCallingContext() {
+#ifdef __ANDROID__
IPCThreadState* ipc = IPCThreadState::self();
const char* callingSid = ipc->getCallingSid();
@@ -108,6 +112,9 @@
.uid = ipc->getCallingUid(),
.sid = callingSid ? std::string(callingSid) : getPidcon(callingPid),
};
+#else
+ return CallingContext();
+#endif
}
bool Access::canFind(const CallingContext& ctx,const std::string& name) {
@@ -124,6 +131,7 @@
bool Access::actionAllowed(const CallingContext& sctx, const char* tctx, const char* perm,
const std::string& tname) {
+#ifdef __ANDROID__
const char* tclass = "service_manager";
AuditCallbackData data = {
@@ -133,9 +141,18 @@
return 0 == selinux_check_access(sctx.sid.c_str(), tctx, tclass, perm,
reinterpret_cast<void*>(&data));
+#else
+ (void)sctx;
+ (void)tctx;
+ (void)perm;
+ (void)tname;
+
+ return true;
+#endif
}
bool Access::actionAllowedFromLookup(const CallingContext& sctx, const std::string& name, const char *perm) {
+#ifdef __ANDROID__
char *tctx = nullptr;
if (selabel_lookup(getSehandle(), &tctx, name.c_str(), SELABEL_CTX_ANDROID_SERVICE) != 0) {
LOG(ERROR) << "SELinux: No match for " << name << " in service_contexts.\n";
@@ -145,6 +162,14 @@
bool allowed = actionAllowed(sctx, tctx, perm, name);
freecon(tctx);
return allowed;
+#else
+ (void)sctx;
+ (void)name;
+ (void)perm;
+ (void)kIsVendor;
+
+ return true;
+#endif
}
} // android
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index 32922ca..8ff838a 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -86,3 +86,35 @@
],
static_libs: ["libgmock"],
}
+
+cc_fuzz {
+ name: "servicemanager_fuzzer",
+ defaults: ["servicemanager_defaults"],
+ host_supported: true,
+ static_libs: [
+ "libbase",
+ "libbinder_random_parcel",
+ "libcutils",
+ ],
+ target: {
+ android: {
+ shared_libs: [
+ "libbinder_ndk",
+ "libbinder",
+ ],
+ },
+ host: {
+ static_libs: [
+ "libbinder_ndk",
+ "libbinder",
+ ],
+ },
+ },
+ srcs: ["ServiceManagerFuzzer.cpp"],
+ fuzz_config: {
+ cc: [
+ "smoreland@google.com",
+ "waghpawan@google.com",
+ ],
+ },
+}
diff --git a/cmds/servicemanager/ServiceManagerFuzzer.cpp b/cmds/servicemanager/ServiceManagerFuzzer.cpp
new file mode 100644
index 0000000..9e2e53f
--- /dev/null
+++ b/cmds/servicemanager/ServiceManagerFuzzer.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fuzzbinder/libbinder_driver.h>
+#include <utils/StrongPointer.h>
+
+#include "Access.h"
+#include "ServiceManager.h"
+
+using ::android::Access;
+using ::android::fuzzService;
+using ::android::ServiceManager;
+using ::android::sp;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ if (size > 50000) {
+ return 0;
+ }
+
+ auto accessPtr = std::make_unique<Access>();
+ auto serviceManager = sp<ServiceManager>::make(std::move(accessPtr));
+ fuzzService(serviceManager, FuzzedDataProvider(data, size));
+
+ return 0;
+}
\ No newline at end of file