blob: 2d55e14feb34b5db8f02e4b7879b3a6537f163ec [file] [log] [blame]
Jeff Sharkey068c6be2017-09-06 13:47:40 -06001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "VoldNativeService.h"
18#include "VolumeManager.h"
19
20#include <fstream>
21
22#include <android-base/logging.h>
23#include <android-base/stringprintf.h>
24#include <android-base/strings.h>
25#include <private/android_filesystem_config.h>
26
27#ifndef LOG_TAG
28#define LOG_TAG "vold"
29#endif
30
31using android::base::StringPrintf;
32using std::endl;
33
34namespace android {
35namespace vold {
36
37namespace {
38
39constexpr const char* kDump = "android.permission.DUMP";
40
41static binder::Status ok() {
42 return binder::Status::ok();
43}
44
45static binder::Status exception(uint32_t code, const std::string& msg) {
46 return binder::Status::fromExceptionCode(code, String8(msg.c_str()));
47}
48
49binder::Status checkPermission(const char* permission) {
50 pid_t pid;
51 uid_t uid;
52
53 if (checkCallingPermission(String16(permission), reinterpret_cast<int32_t*>(&pid),
54 reinterpret_cast<int32_t*>(&uid))) {
55 return ok();
56 } else {
57 return exception(binder::Status::EX_SECURITY,
58 StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission));
59 }
60}
61
62binder::Status checkUid(uid_t expectedUid) {
63 uid_t uid = IPCThreadState::self()->getCallingUid();
64 if (uid == expectedUid || uid == AID_ROOT) {
65 return ok();
66 } else {
67 return exception(binder::Status::EX_SECURITY,
68 StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
69 }
70}
71
72#define ENFORCE_UID(uid) { \
73 binder::Status status = checkUid((uid)); \
74 if (!status.isOk()) { \
75 return status; \
76 } \
77}
78
79} // namespace
80
81status_t VoldNativeService::start() {
82 IPCThreadState::self()->disableBackgroundScheduling(true);
83 status_t ret = BinderService<VoldNativeService>::publish();
84 if (ret != android::OK) {
85 return ret;
86 }
87 sp<ProcessState> ps(ProcessState::self());
88 ps->startThreadPool();
89 ps->giveThreadPoolName();
90 return android::OK;
91}
92
93status_t VoldNativeService::dump(int fd, const Vector<String16> & /* args */) {
94 auto out = std::fstream(StringPrintf("/proc/self/fd/%d", fd));
95 const binder::Status dump_permission = checkPermission(kDump);
96 if (!dump_permission.isOk()) {
97 out << dump_permission.toString8() << endl;
98 return PERMISSION_DENIED;
99 }
100
101 out << "vold is happy!" << endl;
102 out.flush();
103
104 return NO_ERROR;
105}
106
107binder::Status VoldNativeService::reset() {
108 ENFORCE_UID(AID_SYSTEM);
109
110 LOG(INFO) << "reset() via Binder!";
111 VolumeManager::Instance()->reset();
112 return ok();
113}
114
115} // namespace vold
116} // namespace android