From 068c6be6227949fbf34389b2d4c023c2031b005f Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 6 Sep 2017 13:47:40 -0600 Subject: [PATCH] Start paving the way for vold calls over Binder. This change is the bare minimum needed to publish a new vold Binder service and move the simple "reset" call over to go through the new interface. Test: builds, boots Bug: 13758960 Change-Id: I5b70976653c69f92e1efc8d1f432b2038eb618a4 --- Android.mk | 4 ++ VoldNativeService.cpp | 116 +++++++++++++++++++++++++++++++++++ VoldNativeService.h | 39 ++++++++++++ binder/android/os/IVold.aidl | 22 +++++++ main.cpp | 6 ++ 5 files changed, 187 insertions(+) create mode 100644 VoldNativeService.cpp create mode 100644 VoldNativeService.h create mode 100644 binder/android/os/IVold.aidl diff --git a/Android.mk b/Android.mk index 59486d9..f6a8da9 100644 --- a/Android.mk +++ b/Android.mk @@ -35,6 +35,8 @@ common_src_files := \ secontext.cpp \ EncryptInplace.cpp \ MetadataCrypt.cpp \ + binder/android/os/IVold.aidl \ + VoldNativeService.cpp \ common_c_includes := \ system/extras/f2fs_utils \ @@ -129,6 +131,8 @@ LOCAL_SHARED_LIBRARIES := $(common_shared_libraries) LOCAL_STATIC_LIBRARIES := $(common_static_libraries) LOCAL_REQUIRED_MODULES := $(required_modules) +LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder + include $(BUILD_EXECUTABLE) include $(CLEAR_VARS) diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp new file mode 100644 index 0000000..2d55e14 --- /dev/null +++ b/VoldNativeService.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2017 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 "VoldNativeService.h" +#include "VolumeManager.h" + +#include + +#include +#include +#include +#include + +#ifndef LOG_TAG +#define LOG_TAG "vold" +#endif + +using android::base::StringPrintf; +using std::endl; + +namespace android { +namespace vold { + +namespace { + +constexpr const char* kDump = "android.permission.DUMP"; + +static binder::Status ok() { + return binder::Status::ok(); +} + +static binder::Status exception(uint32_t code, const std::string& msg) { + return binder::Status::fromExceptionCode(code, String8(msg.c_str())); +} + +binder::Status checkPermission(const char* permission) { + pid_t pid; + uid_t uid; + + if (checkCallingPermission(String16(permission), reinterpret_cast(&pid), + reinterpret_cast(&uid))) { + return ok(); + } else { + return exception(binder::Status::EX_SECURITY, + StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission)); + } +} + +binder::Status checkUid(uid_t expectedUid) { + uid_t uid = IPCThreadState::self()->getCallingUid(); + if (uid == expectedUid || uid == AID_ROOT) { + return ok(); + } else { + return exception(binder::Status::EX_SECURITY, + StringPrintf("UID %d is not expected UID %d", uid, expectedUid)); + } +} + +#define ENFORCE_UID(uid) { \ + binder::Status status = checkUid((uid)); \ + if (!status.isOk()) { \ + return status; \ + } \ +} + +} // namespace + +status_t VoldNativeService::start() { + IPCThreadState::self()->disableBackgroundScheduling(true); + status_t ret = BinderService::publish(); + if (ret != android::OK) { + return ret; + } + sp ps(ProcessState::self()); + ps->startThreadPool(); + ps->giveThreadPoolName(); + return android::OK; +} + +status_t VoldNativeService::dump(int fd, const Vector & /* args */) { + auto out = std::fstream(StringPrintf("/proc/self/fd/%d", fd)); + const binder::Status dump_permission = checkPermission(kDump); + if (!dump_permission.isOk()) { + out << dump_permission.toString8() << endl; + return PERMISSION_DENIED; + } + + out << "vold is happy!" << endl; + out.flush(); + + return NO_ERROR; +} + +binder::Status VoldNativeService::reset() { + ENFORCE_UID(AID_SYSTEM); + + LOG(INFO) << "reset() via Binder!"; + VolumeManager::Instance()->reset(); + return ok(); +} + +} // namespace vold +} // namespace android diff --git a/VoldNativeService.h b/VoldNativeService.h new file mode 100644 index 0000000..1866059 --- /dev/null +++ b/VoldNativeService.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2017 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. + */ + +#ifndef _VOLD_NATIVE_SERVICE_H_ +#define _VOLD_NATIVE_SERVICE_H_ + +#include + +#include "android/os/BnVold.h" + +namespace android { +namespace vold { + +class VoldNativeService : public BinderService, public os::BnVold { +public: + static status_t start(); + static char const* getServiceName() { return "vold"; } + virtual status_t dump(int fd, const Vector &args) override; + + binder::Status reset(); +}; + +} // namespace vold +} // namespace android + +#endif // _VOLD_NATIVE_SERVICE_H_ diff --git a/binder/android/os/IVold.aidl b/binder/android/os/IVold.aidl new file mode 100644 index 0000000..5f7a3fe --- /dev/null +++ b/binder/android/os/IVold.aidl @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2017 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. + */ + +package android.os; + +/** {@hide} */ +interface IVold { + void reset(); +} diff --git a/main.cpp b/main.cpp index 30c839e..ec240ef 100644 --- a/main.cpp +++ b/main.cpp @@ -19,6 +19,7 @@ #include "CommandListener.h" #include "CryptCommandListener.h" #include "NetlinkManager.h" +#include "VoldNativeService.h" #include "cryptfs.h" #include "sehandle.h" @@ -106,6 +107,11 @@ int main(int argc, char** argv) { exit(1); } + if (android::vold::VoldNativeService::start() != android::OK) { + LOG(ERROR) << "Unable to start VoldNativeService"; + exit(1); + } + bool has_adoptable; bool has_quota;