diff options
author | 2022-07-26 17:06:25 +0000 | |
---|---|---|
committer | 2022-07-26 17:41:45 +0000 | |
commit | ab56a475fb4d2eb7b9ab23bbeefb0a703e31fa41 (patch) | |
tree | 6e1bb03429e0c66c3fe03f1ecf3005fded1f3c19 | |
parent | 05f897cae9b8590c43717b3492e470fa0197c330 (diff) |
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
-rw-r--r-- | cmds/servicemanager/Access.cpp | 27 | ||||
-rw-r--r-- | cmds/servicemanager/Android.bp | 32 | ||||
-rw-r--r-- | cmds/servicemanager/ServiceManagerFuzzer.cpp | 38 |
3 files changed, 96 insertions, 1 deletions
diff --git a/cmds/servicemanager/Access.cpp b/cmds/servicemanager/Access.cpp index b7e520f2f1..711038ce63 100644 --- a/cmds/servicemanager/Access.cpp +++ b/cmds/servicemanager/Access.cpp @@ -30,6 +30,7 @@ constexpr bool kIsVendor = true; constexpr bool kIsVendor = false; #endif +#ifdef __ANDROID__ static std::string getPidcon(pid_t pid) { android_errorWriteLog(0x534e4554, "121035042"); @@ -45,7 +46,6 @@ static std::string getPidcon(pid_t pid) { 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 @@ static int auditCallback(void *data, security_class_t /*cls*/, char *buf, size_t ad->tname->c_str()); return 0; } +#endif Access::Access() { +#ifdef __ANDROID__ union selinux_callback cb; cb.func_audit = auditCallback; @@ -91,6 +93,7 @@ Access::Access() { CHECK(selinux_status_open(true /*fallback*/) >= 0); CHECK(getcon(&mThisProcessContext) == 0); +#endif } Access::~Access() { @@ -98,6 +101,7 @@ Access::~Access() { } Access::CallingContext Access::getCallingContext() { +#ifdef __ANDROID__ IPCThreadState* ipc = IPCThreadState::self(); const char* callingSid = ipc->getCallingSid(); @@ -108,6 +112,9 @@ Access::CallingContext Access::getCallingContext() { .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::canList(const CallingContext& ctx) { 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 @@ bool Access::actionAllowed(const CallingContext& sctx, const char* tctx, const c 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 Access::actionAllowedFromLookup(const CallingContext& sctx, const std::stri 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 32922ca24c..8ff838a1d6 100644 --- a/cmds/servicemanager/Android.bp +++ b/cmds/servicemanager/Android.bp @@ -86,3 +86,35 @@ cc_test { ], 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 0000000000..9e2e53f850 --- /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 |