blob: 3585e966336e35450e9426a4b2e9b2ab08ba3d3b [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"
Jeff Sharkey9462bdd2017-09-07 15:27:28 -060019#include "MoveTask.h"
Jeff Sharkey11c2d382017-09-11 10:32:01 -060020#include "TrimTask.h"
Jeff Sharkey068c6be2017-09-06 13:47:40 -060021
22#include <fstream>
23
24#include <android-base/logging.h>
25#include <android-base/stringprintf.h>
26#include <android-base/strings.h>
Jeff Sharkey11c2d382017-09-11 10:32:01 -060027#include <fs_mgr.h>
Jeff Sharkey068c6be2017-09-06 13:47:40 -060028#include <private/android_filesystem_config.h>
29
30#ifndef LOG_TAG
31#define LOG_TAG "vold"
32#endif
33
34using android::base::StringPrintf;
35using std::endl;
36
37namespace android {
38namespace vold {
39
40namespace {
41
42constexpr const char* kDump = "android.permission.DUMP";
43
44static binder::Status ok() {
45 return binder::Status::ok();
46}
47
48static binder::Status exception(uint32_t code, const std::string& msg) {
49 return binder::Status::fromExceptionCode(code, String8(msg.c_str()));
50}
51
Jeff Sharkey9462bdd2017-09-07 15:27:28 -060052static binder::Status error(const std::string& msg) {
53 PLOG(ERROR) << msg;
54 return binder::Status::fromServiceSpecificError(errno, String8(msg.c_str()));
55}
56
57static binder::Status translate(uint32_t status) {
58 if (status == 0) {
59 return binder::Status::ok();
60 } else {
Jeff Sharkey11c2d382017-09-11 10:32:01 -060061 return binder::Status::fromServiceSpecificError(status);
Jeff Sharkey9462bdd2017-09-07 15:27:28 -060062 }
63}
64
Jeff Sharkey068c6be2017-09-06 13:47:40 -060065binder::Status checkPermission(const char* permission) {
66 pid_t pid;
67 uid_t uid;
68
69 if (checkCallingPermission(String16(permission), reinterpret_cast<int32_t*>(&pid),
70 reinterpret_cast<int32_t*>(&uid))) {
71 return ok();
72 } else {
73 return exception(binder::Status::EX_SECURITY,
74 StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission));
75 }
76}
77
78binder::Status checkUid(uid_t expectedUid) {
79 uid_t uid = IPCThreadState::self()->getCallingUid();
80 if (uid == expectedUid || uid == AID_ROOT) {
81 return ok();
82 } else {
83 return exception(binder::Status::EX_SECURITY,
84 StringPrintf("UID %d is not expected UID %d", uid, expectedUid));
85 }
86}
87
88#define ENFORCE_UID(uid) { \
89 binder::Status status = checkUid((uid)); \
90 if (!status.isOk()) { \
91 return status; \
92 } \
93}
94
Jeff Sharkey9462bdd2017-09-07 15:27:28 -060095#define ACQUIRE_LOCK std::lock_guard<std::mutex> lock(VolumeManager::Instance()->getLock());
96
Jeff Sharkey068c6be2017-09-06 13:47:40 -060097} // namespace
98
99status_t VoldNativeService::start() {
100 IPCThreadState::self()->disableBackgroundScheduling(true);
101 status_t ret = BinderService<VoldNativeService>::publish();
102 if (ret != android::OK) {
103 return ret;
104 }
105 sp<ProcessState> ps(ProcessState::self());
106 ps->startThreadPool();
107 ps->giveThreadPoolName();
108 return android::OK;
109}
110
111status_t VoldNativeService::dump(int fd, const Vector<String16> & /* args */) {
112 auto out = std::fstream(StringPrintf("/proc/self/fd/%d", fd));
113 const binder::Status dump_permission = checkPermission(kDump);
114 if (!dump_permission.isOk()) {
115 out << dump_permission.toString8() << endl;
116 return PERMISSION_DENIED;
117 }
118
Jeff Sharkey9462bdd2017-09-07 15:27:28 -0600119 ACQUIRE_LOCK;
Jeff Sharkey068c6be2017-09-06 13:47:40 -0600120 out << "vold is happy!" << endl;
121 out.flush();
Jeff Sharkey068c6be2017-09-06 13:47:40 -0600122 return NO_ERROR;
123}
124
125binder::Status VoldNativeService::reset() {
126 ENFORCE_UID(AID_SYSTEM);
Jeff Sharkey9462bdd2017-09-07 15:27:28 -0600127 ACQUIRE_LOCK;
Jeff Sharkey068c6be2017-09-06 13:47:40 -0600128
Jeff Sharkey9462bdd2017-09-07 15:27:28 -0600129 return translate(VolumeManager::Instance()->reset());
130}
131
132binder::Status VoldNativeService::shutdown() {
133 ENFORCE_UID(AID_SYSTEM);
134 ACQUIRE_LOCK;
135
136 return translate(VolumeManager::Instance()->shutdown());
137}
138
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600139binder::Status VoldNativeService::mountAll() {
Jeff Sharkey9462bdd2017-09-07 15:27:28 -0600140 ENFORCE_UID(AID_SYSTEM);
141 ACQUIRE_LOCK;
142
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600143 struct fstab* fstab = fs_mgr_read_fstab_default();
144 int res = fs_mgr_mount_all(fstab, MOUNT_MODE_DEFAULT);
145 fs_mgr_free_fstab(fstab);
146 return translate(res);
Jeff Sharkey9462bdd2017-09-07 15:27:28 -0600147}
148
149binder::Status VoldNativeService::onUserAdded(int32_t userId, int32_t userSerial) {
150 ENFORCE_UID(AID_SYSTEM);
151 ACQUIRE_LOCK;
152
153 return translate(VolumeManager::Instance()->onUserAdded(userId, userSerial));
154}
155
156binder::Status VoldNativeService::onUserRemoved(int32_t userId) {
157 ENFORCE_UID(AID_SYSTEM);
158 ACQUIRE_LOCK;
159
160 return translate(VolumeManager::Instance()->onUserRemoved(userId));
161}
162
163binder::Status VoldNativeService::onUserStarted(int32_t userId) {
164 ENFORCE_UID(AID_SYSTEM);
165 ACQUIRE_LOCK;
166
167 return translate(VolumeManager::Instance()->onUserStarted(userId));
168}
169
170binder::Status VoldNativeService::onUserStopped(int32_t userId) {
171 ENFORCE_UID(AID_SYSTEM);
172 ACQUIRE_LOCK;
173
174 return translate(VolumeManager::Instance()->onUserStopped(userId));
175}
176
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600177binder::Status VoldNativeService::partition(const std::string& diskId, int32_t partitionType,
178 int32_t ratio) {
Jeff Sharkey9462bdd2017-09-07 15:27:28 -0600179 ENFORCE_UID(AID_SYSTEM);
180 ACQUIRE_LOCK;
181
182 auto disk = VolumeManager::Instance()->findDisk(diskId);
183 if (disk == nullptr) {
184 return error("Failed to find disk " + diskId);
185 }
186 switch (partitionType) {
187 case PARTITION_TYPE_PUBLIC: return translate(disk->partitionPublic());
188 case PARTITION_TYPE_PRIVATE: return translate(disk->partitionPrivate());
189 case PARTITION_TYPE_MIXED: return translate(disk->partitionMixed(ratio));
190 default: return error("Unknown type " + std::to_string(partitionType));
191 }
192}
193
194binder::Status VoldNativeService::forgetPartition(const std::string& partGuid) {
195 ENFORCE_UID(AID_SYSTEM);
196 ACQUIRE_LOCK;
197
198 return translate(VolumeManager::Instance()->forgetPartition(partGuid));
199}
200
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600201binder::Status VoldNativeService::mount(const std::string& volId, int32_t mountFlags,
202 int32_t mountUserId) {
Jeff Sharkey9462bdd2017-09-07 15:27:28 -0600203 ENFORCE_UID(AID_SYSTEM);
204 ACQUIRE_LOCK;
205
206 auto vol = VolumeManager::Instance()->findVolume(volId);
207 if (vol == nullptr) {
208 return error("Failed to find volume " + volId);
209 }
210
211 vol->setMountFlags(mountFlags);
212 vol->setMountUserId(mountUserId);
213
214 int res = vol->mount();
215 if (mountFlags & MOUNT_FLAG_PRIMARY) {
216 VolumeManager::Instance()->setPrimary(vol);
217 }
218 return translate(res);
219}
220
221binder::Status VoldNativeService::unmount(const std::string& volId) {
222 ENFORCE_UID(AID_SYSTEM);
223 ACQUIRE_LOCK;
224
225 auto vol = VolumeManager::Instance()->findVolume(volId);
226 if (vol == nullptr) {
227 return error("Failed to find volume " + volId);
228 }
229 return translate(vol->unmount());
230}
231
232binder::Status VoldNativeService::format(const std::string& volId, const std::string& fsType) {
233 ENFORCE_UID(AID_SYSTEM);
234 ACQUIRE_LOCK;
235
236 auto vol = VolumeManager::Instance()->findVolume(volId);
237 if (vol == nullptr) {
238 return error("Failed to find volume " + volId);
239 }
240 return translate(vol->format(fsType));
241}
242
243binder::Status VoldNativeService::benchmark(const std::string& volId, int64_t* _aidl_return) {
244 ENFORCE_UID(AID_SYSTEM);
245 ACQUIRE_LOCK;
246
247 *_aidl_return = VolumeManager::Instance()->benchmarkPrivate(volId);
Jeff Sharkey068c6be2017-09-06 13:47:40 -0600248 return ok();
249}
250
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600251binder::Status VoldNativeService::moveStorage(const std::string& fromVolId,
252 const std::string& toVolId) {
Jeff Sharkey9462bdd2017-09-07 15:27:28 -0600253 ENFORCE_UID(AID_SYSTEM);
254 ACQUIRE_LOCK;
255
256 auto fromVol = VolumeManager::Instance()->findVolume(fromVolId);
257 auto toVol = VolumeManager::Instance()->findVolume(toVolId);
258 if (fromVol == nullptr) {
259 return error("Failed to find volume " + fromVolId);
260 } else if (toVol == nullptr) {
261 return error("Failed to find volume " + toVolId);
262 }
263 (new android::vold::MoveTask(fromVol, toVol))->start();
264 return ok();
265}
266
267binder::Status VoldNativeService::remountUid(int32_t uid, int32_t remountMode) {
268 ENFORCE_UID(AID_SYSTEM);
269 ACQUIRE_LOCK;
270
271 std::string tmp;
272 switch (remountMode) {
273 case REMOUNT_MODE_NONE: tmp = "none"; break;
274 case REMOUNT_MODE_DEFAULT: tmp = "default"; break;
275 case REMOUNT_MODE_READ: tmp = "read"; break;
276 case REMOUNT_MODE_WRITE: tmp = "write"; break;
277 default: return error("Unknown mode " + std::to_string(remountMode));
278 }
279 return translate(VolumeManager::Instance()->remountUid(uid, tmp));
280}
281
282binder::Status VoldNativeService::mkdirs(const std::string& path) {
283 ENFORCE_UID(AID_SYSTEM);
284 ACQUIRE_LOCK;
285
286 return translate(VolumeManager::Instance()->mkdirs(path.c_str()));
287}
288
Jeff Sharkey11c2d382017-09-11 10:32:01 -0600289binder::Status VoldNativeService::createObb(const std::string& sourcePath,
290 const std::string& sourceKey, int32_t ownerGid, std::string* _aidl_return) {
291 ENFORCE_UID(AID_SYSTEM);
292 ACQUIRE_LOCK;
293
294 return translate(
295 VolumeManager::Instance()->createObb(sourcePath, sourceKey, ownerGid, _aidl_return));
296}
297
298binder::Status VoldNativeService::destroyObb(const std::string& volId) {
299 ENFORCE_UID(AID_SYSTEM);
300 ACQUIRE_LOCK;
301
302 return translate(VolumeManager::Instance()->destroyObb(volId));
303}
304
305binder::Status VoldNativeService::fstrim(int32_t fstrimFlags) {
306 ENFORCE_UID(AID_SYSTEM);
307 ACQUIRE_LOCK;
308
309 (new android::vold::TrimTask(fstrimFlags))->start();
310 return ok();
311}
312
313binder::Status VoldNativeService::mountAppFuse(int32_t uid, int32_t pid, int32_t mountId,
314 android::base::unique_fd* _aidl_return) {
315 ENFORCE_UID(AID_SYSTEM);
316 ACQUIRE_LOCK;
317
318 return translate(VolumeManager::Instance()->mountAppFuse(uid, pid, mountId, _aidl_return));
319}
320
321binder::Status VoldNativeService::unmountAppFuse(int32_t uid, int32_t pid, int32_t mountId) {
322 ENFORCE_UID(AID_SYSTEM);
323 ACQUIRE_LOCK;
324
325 return translate(VolumeManager::Instance()->unmountAppFuse(uid, pid, mountId));
326}
327
Jeff Sharkey068c6be2017-09-06 13:47:40 -0600328} // namespace vold
329} // namespace android