1deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey/* 2deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * Copyright (C) 2015 The Android Open Source Project 3deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * 4deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * Licensed under the Apache License, Version 2.0 (the "License"); 5deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * you may not use this file except in compliance with the License. 6deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * You may obtain a copy of the License at 7deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * 8deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * http://www.apache.org/licenses/LICENSE-2.0 9deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * 10deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * Unless required by applicable law or agreed to in writing, software 11deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * distributed under the License is distributed on an "AS IS" BASIS, 12deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * See the License for the specific language governing permissions and 14deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey * limitations under the License. 15deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey */ 16deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 17deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include "sehandle.h" 18deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include "Utils.h" 19deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include "Process.h" 20deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 217e128fbe212c64492afa98bfd6d7fab6f1956831Elliott Hughes#include <android-base/file.h> 227e128fbe212c64492afa98bfd6d7fab6f1956831Elliott Hughes#include <android-base/logging.h> 237e128fbe212c64492afa98bfd6d7fab6f1956831Elliott Hughes#include <android-base/stringprintf.h> 24deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include <cutils/fs.h> 25c86ab6f538bec63638c168d6c843fe7cf73add3bJeff Sharkey#include <cutils/properties.h> 26deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include <private/android_filesystem_config.h> 279c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey#include <logwrap/logwrap.h> 28deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 29ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey#include <mutex> 301d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey#include <dirent.h> 31deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include <fcntl.h> 32deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include <linux/fs.h> 33deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include <stdlib.h> 34deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include <sys/mount.h> 35deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include <sys/types.h> 36deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include <sys/stat.h> 37deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#include <sys/wait.h> 381d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey#include <sys/statvfs.h> 39deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 40deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#ifndef UMOUNT_NOFOLLOW 41deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#define UMOUNT_NOFOLLOW 0x00000008 /* Don't follow symlink on umount */ 42deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey#endif 43deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 44d0640f6358041f7e2657167560b357078db73526Jeff Sharkeyusing android::base::ReadFileToString; 459c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeyusing android::base::StringPrintf; 469c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 47deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkeynamespace android { 48deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkeynamespace vold { 49deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 5095c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkeysecurity_context_t sBlkidContext = nullptr; 5195c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkeysecurity_context_t sBlkidUntrustedContext = nullptr; 5295c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkeysecurity_context_t sFsckContext = nullptr; 5395c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkeysecurity_context_t sFsckUntrustedContext = nullptr; 5495c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkey 559c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeystatic const char* kBlkidPath = "/system/bin/blkid"; 56bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkeystatic const char* kKeyPath = "/data/misc/vold"; 579c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 58d0640f6358041f7e2657167560b357078db73526Jeff Sharkeystatic const char* kProcFilesystems = "/proc/filesystems"; 59d0640f6358041f7e2657167560b357078db73526Jeff Sharkey 60deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkeystatus_t CreateDeviceNode(const std::string& path, dev_t dev) { 61deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey const char* cpath = path.c_str(); 62deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey status_t res = 0; 63deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 64deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey char* secontext = nullptr; 65deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey if (sehandle) { 66deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey if (!selabel_lookup(sehandle, &secontext, cpath, S_IFBLK)) { 67deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey setfscreatecon(secontext); 68deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey } 69deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey } 70deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 71deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey mode_t mode = 0660 | S_IFBLK; 72deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey if (mknod(cpath, mode, dev) < 0) { 73deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey if (errno != EEXIST) { 7436801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey PLOG(ERROR) << "Failed to create device node for " << major(dev) 7536801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey << ":" << minor(dev) << " at " << path; 76deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey res = -errno; 77deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey } 78deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey } 79deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 80deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey if (secontext) { 81deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey setfscreatecon(nullptr); 82deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey freecon(secontext); 83deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey } 84deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 85deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey return res; 86deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey} 87deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 88deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkeystatus_t DestroyDeviceNode(const std::string& path) { 89deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey const char* cpath = path.c_str(); 90deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey if (TEMP_FAILURE_RETRY(unlink(cpath))) { 91deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey return -errno; 92deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey } else { 93deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey return OK; 94deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey } 95deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey} 96deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 97f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkeystatus_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid) { 98f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey const char* cpath = path.c_str(); 99f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey 100f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey char* secontext = nullptr; 101f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey if (sehandle) { 102f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey if (!selabel_lookup(sehandle, &secontext, cpath, S_IFDIR)) { 103f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey setfscreatecon(secontext); 104f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey } 105f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey } 106f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey 107f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey int res = fs_prepare_dir(cpath, mode, uid, gid); 108f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey 109f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey if (secontext) { 110f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey setfscreatecon(nullptr); 111f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey freecon(secontext); 112f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey } 113f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey 114f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey if (res == 0) { 115f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey return OK; 116f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey } else { 117f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey return -errno; 118f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey } 119f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey} 120f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey 121deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkeystatus_t ForceUnmount(const std::string& path) { 122deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey const char* cpath = path.c_str(); 123deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) { 124deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey return OK; 125deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey } 12689f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey // Apps might still be handling eject request, so wait before 12789f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey // we start sending signals 1289c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey sleep(5); 129ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey 13089f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey Process::killProcessesWithOpenFiles(cpath, SIGINT); 13189f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey sleep(5); 132ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) { 133ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey return OK; 134ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey } 135ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey 136f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey Process::killProcessesWithOpenFiles(cpath, SIGTERM); 13789f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey sleep(5); 138deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) { 139deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey return OK; 140deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey } 141f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey 142f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey Process::killProcessesWithOpenFiles(cpath, SIGKILL); 14389f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey sleep(5); 144deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey if (!umount2(cpath, UMOUNT_NOFOLLOW) || errno == EINVAL || errno == ENOENT) { 145deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey return OK; 146deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey } 147f0121c574ede0898e36eeba0a0e0affd0f8d81a7Jeff Sharkey 148deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey return -errno; 149deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey} 150deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey 15189f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkeystatus_t KillProcessesUsingPath(const std::string& path) { 15289f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey const char* cpath = path.c_str(); 15389f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey if (Process::killProcessesWithOpenFiles(cpath, SIGINT) == 0) { 15489f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey return OK; 15589f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey } 15689f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey sleep(5); 15789f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey 15889f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey if (Process::killProcessesWithOpenFiles(cpath, SIGTERM) == 0) { 15989f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey return OK; 16089f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey } 16189f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey sleep(5); 16289f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey 16389f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey if (Process::killProcessesWithOpenFiles(cpath, SIGKILL) == 0) { 16489f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey return OK; 16589f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey } 16689f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey sleep(5); 16789f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey 16889f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey // Send SIGKILL a second time to determine if we've 16989f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey // actually killed everyone with open files 17089f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey if (Process::killProcessesWithOpenFiles(cpath, SIGKILL) == 0) { 17189f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey return OK; 17289f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey } 17389f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey PLOG(ERROR) << "Failed to kill processes using " << path; 17489f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey return -EBUSY; 17589f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey} 17689f74fbf2529d708534c041d2b711af0f1feff9fJeff Sharkey 17736801cccf27152c9eca5aab6ba3527221525110fJeff Sharkeystatus_t BindMount(const std::string& source, const std::string& target) { 17836801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey if (::mount(source.c_str(), target.c_str(), "", MS_BIND, NULL)) { 17936801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey PLOG(ERROR) << "Failed to bind mount " << source << " to " << target; 18036801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey return -errno; 18136801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey } 18236801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey return OK; 18336801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey} 18436801cccf27152c9eca5aab6ba3527221525110fJeff Sharkey 18595c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkeystatic status_t readMetadata(const std::string& path, std::string& fsType, 18695c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkey std::string& fsUuid, std::string& fsLabel, bool untrusted) { 1879c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey fsType.clear(); 1889c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey fsUuid.clear(); 1899c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey fsLabel.clear(); 1909c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 191ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey std::vector<std::string> cmd; 192ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey cmd.push_back(kBlkidPath); 193ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey cmd.push_back("-c"); 194ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey cmd.push_back("/dev/null"); 195eddf9bd63c1f7e0f9709f7c58a1035fa43338325Jeff Sharkey cmd.push_back("-s"); 196eddf9bd63c1f7e0f9709f7c58a1035fa43338325Jeff Sharkey cmd.push_back("TYPE"); 197eddf9bd63c1f7e0f9709f7c58a1035fa43338325Jeff Sharkey cmd.push_back("-s"); 198eddf9bd63c1f7e0f9709f7c58a1035fa43338325Jeff Sharkey cmd.push_back("UUID"); 199eddf9bd63c1f7e0f9709f7c58a1035fa43338325Jeff Sharkey cmd.push_back("-s"); 200eddf9bd63c1f7e0f9709f7c58a1035fa43338325Jeff Sharkey cmd.push_back("LABEL"); 201ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey cmd.push_back(path); 202ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey 203ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey std::vector<std::string> output; 204ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey status_t res = ForkExecvp(cmd, output, untrusted ? sBlkidUntrustedContext : sBlkidContext); 205ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if (res != OK) { 206ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey LOG(WARNING) << "blkid failed to identify " << path; 207ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey return res; 2089c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 2099c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 2109c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey char value[128]; 21111a2ce8da33e0ec4be250fd85c47f706d6c91a10Chih-Hung Hsieh for (const auto& line : output) { 2129c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey // Extract values from blkid output, if defined 213ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey const char* cline = line.c_str(); 21449ab5f9e6db637ad76ef75f5397f9cc919ada21dDan Austin const char* start = strstr(cline, "TYPE="); 2159c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey if (start != nullptr && sscanf(start + 5, "\"%127[^\"]\"", value) == 1) { 2169c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey fsType = value; 2179c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 2189c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 219ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey start = strstr(cline, "UUID="); 2209c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey if (start != nullptr && sscanf(start + 5, "\"%127[^\"]\"", value) == 1) { 2219c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey fsUuid = value; 2229c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 2239c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 224ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey start = strstr(cline, "LABEL="); 2259c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey if (start != nullptr && sscanf(start + 6, "\"%127[^\"]\"", value) == 1) { 2269c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey fsLabel = value; 2279c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 2289c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 2299c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 230ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey return OK; 2319c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey} 2329c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 23395c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkeystatus_t ReadMetadata(const std::string& path, std::string& fsType, 23495c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkey std::string& fsUuid, std::string& fsLabel) { 23595c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkey return readMetadata(path, fsType, fsUuid, fsLabel, false); 23695c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkey} 23795c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkey 23895c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkeystatus_t ReadMetadataUntrusted(const std::string& path, std::string& fsType, 23995c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkey std::string& fsUuid, std::string& fsLabel) { 24095c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkey return readMetadata(path, fsType, fsUuid, fsLabel, true); 24195c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkey} 24295c87cce353ca2da79aa57a3a5336b45b6f1d018Jeff Sharkey 243ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkeystatus_t ForkExecvp(const std::vector<std::string>& args) { 244ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey return ForkExecvp(args, nullptr); 245ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey} 246ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey 247ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkeystatus_t ForkExecvp(const std::vector<std::string>& args, security_context_t context) { 248ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey size_t argc = args.size(); 2499c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey char** argv = (char**) calloc(argc, sizeof(char*)); 250ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey for (size_t i = 0; i < argc; i++) { 2519c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey argv[i] = (char*) args[i].c_str(); 2529c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey if (i == 0) { 2539c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey LOG(VERBOSE) << args[i]; 2549c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } else { 2559c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey LOG(VERBOSE) << " " << args[i]; 2569c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 2579c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 258ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey 2591d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (setexeccon(context)) { 2601d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey LOG(ERROR) << "Failed to setexeccon"; 2611d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey abort(); 2621d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 2631d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey status_t res = android_fork_execvp(argc, argv, NULL, false, true); 2641d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (setexeccon(nullptr)) { 2651d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey LOG(ERROR) << "Failed to setexeccon"; 2661d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey abort(); 267ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey } 2681d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 2699c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey free(argv); 2709c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey return res; 2719c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey} 2729c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 273ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkeystatus_t ForkExecvp(const std::vector<std::string>& args, 274ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey std::vector<std::string>& output) { 275ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey return ForkExecvp(args, output, nullptr); 276ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey} 277ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey 278ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkeystatus_t ForkExecvp(const std::vector<std::string>& args, 279ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey std::vector<std::string>& output, security_context_t context) { 280ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey std::string cmd; 281ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey for (size_t i = 0; i < args.size(); i++) { 282ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey cmd += args[i] + " "; 283ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if (i == 0) { 284ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey LOG(VERBOSE) << args[i]; 285ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey } else { 286ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey LOG(VERBOSE) << " " << args[i]; 287ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey } 288ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey } 289ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey output.clear(); 290ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey 2911d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (setexeccon(context)) { 2921d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey LOG(ERROR) << "Failed to setexeccon"; 2931d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey abort(); 2941d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 2951d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey FILE* fp = popen(cmd.c_str(), "r"); 2961d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (setexeccon(nullptr)) { 2971d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey LOG(ERROR) << "Failed to setexeccon"; 2981d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey abort(); 299ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey } 300ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey 301ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if (!fp) { 302ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey PLOG(ERROR) << "Failed to popen " << cmd; 303ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey return -errno; 304ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey } 305ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey char line[1024]; 306ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey while (fgets(line, sizeof(line), fp) != nullptr) { 307ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey LOG(VERBOSE) << line; 308ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey output.push_back(std::string(line)); 309ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey } 310ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey if (pclose(fp) != 0) { 311ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey PLOG(ERROR) << "Failed to pclose " << cmd; 312ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey return -errno; 313ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey } 314ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey 315ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey return OK; 316ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey} 317ce6a913aeac7db94a41362c63bab74092767bb3eJeff Sharkey 3181d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeypid_t ForkExecvpAsync(const std::vector<std::string>& args) { 3191d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey size_t argc = args.size(); 3201d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey char** argv = (char**) calloc(argc + 1, sizeof(char*)); 3211d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey for (size_t i = 0; i < argc; i++) { 3221d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey argv[i] = (char*) args[i].c_str(); 3231d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (i == 0) { 3241d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey LOG(VERBOSE) << args[i]; 3251d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } else { 3261d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey LOG(VERBOSE) << " " << args[i]; 3271d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 3281d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 3291d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 3301d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey pid_t pid = fork(); 3311d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (pid == 0) { 3321d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey close(STDIN_FILENO); 3331d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey close(STDOUT_FILENO); 3341d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey close(STDERR_FILENO); 3351d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 3361d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (execvp(argv[0], argv)) { 3371d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey PLOG(ERROR) << "Failed to exec"; 3381d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 3391d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 3401d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey _exit(1); 3411d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 3421d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 3431d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (pid == -1) { 3441d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey PLOG(ERROR) << "Failed to exec"; 3451d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 3461d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 3471d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey free(argv); 3481d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return pid; 3491d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 3501d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 3519c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeystatus_t ReadRandomBytes(size_t bytes, std::string& out) { 3529c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey out.clear(); 3539c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 3549c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey int fd = TEMP_FAILURE_RETRY(open("/dev/urandom", O_RDONLY | O_CLOEXEC | O_NOFOLLOW)); 3559c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey if (fd == -1) { 3569c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey return -errno; 3579c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 3589c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 3599c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey char buf[BUFSIZ]; 3609c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey size_t n; 3619c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], std::min(sizeof(buf), bytes)))) > 0) { 3629c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey out.append(buf, n); 3639c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey bytes -= n; 3649c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 365a623108ef40143e04e3e765a057981a439ff3cd2Elliott Hughes close(fd); 3669c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 3679c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey if (bytes == 0) { 3689c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey return OK; 3699c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } else { 3709c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey return -EIO; 3719c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 3729c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey} 3739c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 3749c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeystatus_t HexToStr(const std::string& hex, std::string& str) { 3759c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey str.clear(); 3769c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey bool even = true; 3779c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey char cur = 0; 3789c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey for (size_t i = 0; i < hex.size(); i++) { 3799c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey int val = 0; 3809c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey switch (hex[i]) { 3819c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case ' ': case '-': case ':': continue; 3829c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case 'f': case 'F': val = 15; break; 3839c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case 'e': case 'E': val = 14; break; 3849c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case 'd': case 'D': val = 13; break; 3859c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case 'c': case 'C': val = 12; break; 3869c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case 'b': case 'B': val = 11; break; 3879c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case 'a': case 'A': val = 10; break; 3889c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case '9': val = 9; break; 3899c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case '8': val = 8; break; 3909c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case '7': val = 7; break; 3919c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case '6': val = 6; break; 3929c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case '5': val = 5; break; 3939c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case '4': val = 4; break; 3949c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case '3': val = 3; break; 3959c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case '2': val = 2; break; 3969c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case '1': val = 1; break; 3979c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey case '0': val = 0; break; 3989c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey default: return -EINVAL; 3999c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 4009c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 4019c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey if (even) { 4029c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey cur = val << 4; 4039c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } else { 4049c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey cur += val; 4059c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey str.push_back(cur); 4069c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey cur = 0; 4079c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 4089c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey even = !even; 4099c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 4109c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey return even ? OK : -EINVAL; 4119c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey} 4129c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 4139c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeystatic const char* kLookup = "0123456789abcdef"; 4149c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 4159c48498f4529f623650c56d03e63324c8d813032Jeff Sharkeystatus_t StrToHex(const std::string& str, std::string& hex) { 4169c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey hex.clear(); 4179c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey for (size_t i = 0; i < str.size(); i++) { 418ef3697545bc7fadec43001fa3c8376426510b9eaJeff Sharkey hex.push_back(kLookup[(str[i] & 0xF0) >> 4]); 4199c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey hex.push_back(kLookup[str[i] & 0x0F]); 4209c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey } 4219c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey return OK; 4229c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey} 4239c48498f4529f623650c56d03e63324c8d813032Jeff Sharkey 424bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkeystatus_t NormalizeHex(const std::string& in, std::string& out) { 425bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkey std::string tmp; 426bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkey if (HexToStr(in, tmp)) { 427bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkey return -EINVAL; 428bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkey } 429bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkey return StrToHex(tmp, out); 430bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkey} 431bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkey 4321d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeyuint64_t GetFreeBytes(const std::string& path) { 4331d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey struct statvfs sb; 4341d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (statvfs(path.c_str(), &sb) == 0) { 435a0220a5bd410d4b342ee1ca84e8381d6bc5f468eJeff Sharkey return (uint64_t) sb.f_bavail * sb.f_frsize; 4361d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } else { 4371d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return -1; 4381d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 4391d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 4401d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 4411d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey// TODO: borrowed from frameworks/native/libs/diskusage/ which should 4421d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey// eventually be migrated into system/ 4431d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeystatic int64_t stat_size(struct stat *s) { 4441d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey int64_t blksize = s->st_blksize; 4451d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey // count actual blocks used instead of nominal file size 4461d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey int64_t size = s->st_blocks * 512; 4471d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 4481d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (blksize) { 4491d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey /* round up to filesystem block size */ 4501d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey size = (size + blksize - 1) & (~(blksize - 1)); 4511d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 4521d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 4531d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return size; 4541d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 4551d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 4561d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey// TODO: borrowed from frameworks/native/libs/diskusage/ which should 4571d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey// eventually be migrated into system/ 4581d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeyint64_t calculate_dir_size(int dfd) { 4591d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey int64_t size = 0; 4601d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey struct stat s; 4611d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey DIR *d; 4621d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey struct dirent *de; 4631d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 4641d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey d = fdopendir(dfd); 4651d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (d == NULL) { 4661d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey close(dfd); 4671d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return 0; 4681d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 4691d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 4701d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey while ((de = readdir(d))) { 4711d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey const char *name = de->d_name; 4721d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (fstatat(dfd, name, &s, AT_SYMLINK_NOFOLLOW) == 0) { 4731d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey size += stat_size(&s); 4741d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 4751d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (de->d_type == DT_DIR) { 4761d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey int subfd; 4771d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 4781d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey /* always skip "." and ".." */ 4791d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (name[0] == '.') { 4801d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (name[1] == 0) 4811d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey continue; 4821d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if ((name[1] == '.') && (name[2] == 0)) 4831d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey continue; 4841d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 4851d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 486fd3dc3c076f30e19e7ac902ba0531c6bcfe2e042Jeff Sharkey subfd = openat(dfd, name, O_RDONLY | O_DIRECTORY | O_CLOEXEC); 4871d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (subfd >= 0) { 4881d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey size += calculate_dir_size(subfd); 4891d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 4901d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 4911d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 4921d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey closedir(d); 4931d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return size; 4941d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 4951d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 4961d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkeyuint64_t GetTreeBytes(const std::string& path) { 497fd3dc3c076f30e19e7ac902ba0531c6bcfe2e042Jeff Sharkey int dirfd = open(path.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC); 4981d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey if (dirfd < 0) { 4991d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey PLOG(WARNING) << "Failed to open " << path; 5001d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return -1; 5011d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } else { 5021d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey uint64_t res = calculate_dir_size(dirfd); 5031d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey close(dirfd); 5041d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey return res; 5051d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey } 5061d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey} 5071d6fbcc389ecb9f418076e8ab5f4c93a5d911de9Jeff Sharkey 508d0640f6358041f7e2657167560b357078db73526Jeff Sharkeybool IsFilesystemSupported(const std::string& fsType) { 509d0640f6358041f7e2657167560b357078db73526Jeff Sharkey std::string supported; 510d0640f6358041f7e2657167560b357078db73526Jeff Sharkey if (!ReadFileToString(kProcFilesystems, &supported)) { 511d0640f6358041f7e2657167560b357078db73526Jeff Sharkey PLOG(ERROR) << "Failed to read supported filesystems"; 512d0640f6358041f7e2657167560b357078db73526Jeff Sharkey return false; 513d0640f6358041f7e2657167560b357078db73526Jeff Sharkey } 514d0640f6358041f7e2657167560b357078db73526Jeff Sharkey return supported.find(fsType + "\n") != std::string::npos; 515d0640f6358041f7e2657167560b357078db73526Jeff Sharkey} 516d0640f6358041f7e2657167560b357078db73526Jeff Sharkey 517d0640f6358041f7e2657167560b357078db73526Jeff Sharkeystatus_t WipeBlockDevice(const std::string& path) { 518d0640f6358041f7e2657167560b357078db73526Jeff Sharkey status_t res = -1; 519d0640f6358041f7e2657167560b357078db73526Jeff Sharkey const char* c_path = path.c_str(); 520d0640f6358041f7e2657167560b357078db73526Jeff Sharkey unsigned long nr_sec = 0; 521d0640f6358041f7e2657167560b357078db73526Jeff Sharkey unsigned long long range[2]; 522d0640f6358041f7e2657167560b357078db73526Jeff Sharkey 523d0640f6358041f7e2657167560b357078db73526Jeff Sharkey int fd = TEMP_FAILURE_RETRY(open(c_path, O_RDWR | O_CLOEXEC)); 524d0640f6358041f7e2657167560b357078db73526Jeff Sharkey if (fd == -1) { 525d0640f6358041f7e2657167560b357078db73526Jeff Sharkey PLOG(ERROR) << "Failed to open " << path; 526d0640f6358041f7e2657167560b357078db73526Jeff Sharkey goto done; 527d0640f6358041f7e2657167560b357078db73526Jeff Sharkey } 528d0640f6358041f7e2657167560b357078db73526Jeff Sharkey 5299102b0b1757cea7abe1217efda6943d23292fed8caozhiyuan if ((ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) { 530d0640f6358041f7e2657167560b357078db73526Jeff Sharkey PLOG(ERROR) << "Failed to determine size of " << path; 531d0640f6358041f7e2657167560b357078db73526Jeff Sharkey goto done; 532d0640f6358041f7e2657167560b357078db73526Jeff Sharkey } 533d0640f6358041f7e2657167560b357078db73526Jeff Sharkey 534d0640f6358041f7e2657167560b357078db73526Jeff Sharkey range[0] = 0; 535d0640f6358041f7e2657167560b357078db73526Jeff Sharkey range[1] = (unsigned long long) nr_sec * 512; 536d0640f6358041f7e2657167560b357078db73526Jeff Sharkey 537d0640f6358041f7e2657167560b357078db73526Jeff Sharkey LOG(INFO) << "About to discard " << range[1] << " on " << path; 538d0640f6358041f7e2657167560b357078db73526Jeff Sharkey if (ioctl(fd, BLKDISCARD, &range) == 0) { 539d0640f6358041f7e2657167560b357078db73526Jeff Sharkey LOG(INFO) << "Discard success on " << path; 540d0640f6358041f7e2657167560b357078db73526Jeff Sharkey res = 0; 541d0640f6358041f7e2657167560b357078db73526Jeff Sharkey } else { 542d0640f6358041f7e2657167560b357078db73526Jeff Sharkey PLOG(ERROR) << "Discard failure on " << path; 543d0640f6358041f7e2657167560b357078db73526Jeff Sharkey } 544d0640f6358041f7e2657167560b357078db73526Jeff Sharkey 545d0640f6358041f7e2657167560b357078db73526Jeff Sharkeydone: 546d0640f6358041f7e2657167560b357078db73526Jeff Sharkey close(fd); 547d0640f6358041f7e2657167560b357078db73526Jeff Sharkey return res; 548d0640f6358041f7e2657167560b357078db73526Jeff Sharkey} 549d0640f6358041f7e2657167560b357078db73526Jeff Sharkey 550d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkeystatic bool isValidFilename(const std::string& name) { 551d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey if (name.empty() || (name == ".") || (name == "..") 552d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey || (name.find('/') != std::string::npos)) { 553d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey return false; 554d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey } else { 555d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey return true; 556d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey } 557d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey} 558d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey 559bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkeystd::string BuildKeyPath(const std::string& partGuid) { 560bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkey return StringPrintf("%s/expand_%s.key", kKeyPath, partGuid.c_str()); 561bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkey} 562bc40cc8f07f69e0e26fc41516e2a83f0a8becbe0Jeff Sharkey 563be70c9ae2251ac8f3bfbbe75146f8c533d64e01bJeff Sharkeystd::string BuildDataSystemLegacyPath(userid_t userId) { 564be70c9ae2251ac8f3bfbbe75146f8c533d64e01bJeff Sharkey return StringPrintf("%s/system/users/%u", BuildDataPath(nullptr).c_str(), userId); 565be70c9ae2251ac8f3bfbbe75146f8c533d64e01bJeff Sharkey} 566be70c9ae2251ac8f3bfbbe75146f8c533d64e01bJeff Sharkey 567d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkeystd::string BuildDataSystemCePath(userid_t userId) { 56847695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey return StringPrintf("%s/system_ce/%u", BuildDataPath(nullptr).c_str(), userId); 56947695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey} 57047695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey 57147695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkeystd::string BuildDataSystemDePath(userid_t userId) { 57247695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey return StringPrintf("%s/system_de/%u", BuildDataPath(nullptr).c_str(), userId); 57347695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey} 57447695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey 575be70c9ae2251ac8f3bfbbe75146f8c533d64e01bJeff Sharkeystd::string BuildDataMiscLegacyPath(userid_t userId) { 576be70c9ae2251ac8f3bfbbe75146f8c533d64e01bJeff Sharkey return StringPrintf("%s/misc/user/%u", BuildDataPath(nullptr).c_str(), userId); 577be70c9ae2251ac8f3bfbbe75146f8c533d64e01bJeff Sharkey} 578be70c9ae2251ac8f3bfbbe75146f8c533d64e01bJeff Sharkey 57947695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkeystd::string BuildDataMiscCePath(userid_t userId) { 58047695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey return StringPrintf("%s/misc_ce/%u", BuildDataPath(nullptr).c_str(), userId); 58147695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey} 58247695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey 58347695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkeystd::string BuildDataMiscDePath(userid_t userId) { 58447695b29af0467dd8e18f5534e3b62e39326d7e1Jeff Sharkey return StringPrintf("%s/misc_de/%u", BuildDataPath(nullptr).c_str(), userId); 585d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey} 586d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey 58779f55a461f1edf90b769824c6a69dcb520614d83Calin Juravle// Keep in sync with installd (frameworks/native/cmds/installd/utils.h) 58879f55a461f1edf90b769824c6a69dcb520614d83Calin Juravlestd::string BuildDataProfilesDePath(userid_t userId) { 58979f55a461f1edf90b769824c6a69dcb520614d83Calin Juravle return StringPrintf("%s/misc/profiles/cur/%u", BuildDataPath(nullptr).c_str(), userId); 59079f55a461f1edf90b769824c6a69dcb520614d83Calin Juravle} 59179f55a461f1edf90b769824c6a69dcb520614d83Calin Juravle 592d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkeystd::string BuildDataPath(const char* volumeUuid) { 593d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey // TODO: unify with installd path generation logic 594d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey if (volumeUuid == nullptr) { 595d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey return "/data"; 596d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey } else { 597d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey CHECK(isValidFilename(volumeUuid)); 598d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey return StringPrintf("/mnt/expand/%s", volumeUuid); 599d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey } 600d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey} 601d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey 602be70c9ae2251ac8f3bfbbe75146f8c533d64e01bJeff Sharkeystd::string BuildDataMediaCePath(const char* volumeUuid, userid_t userId) { 603fc505c3ff6c1ba3a061e7e8b3f2236be90712a80Jeff Sharkey // TODO: unify with installd path generation logic 604fc505c3ff6c1ba3a061e7e8b3f2236be90712a80Jeff Sharkey std::string data(BuildDataPath(volumeUuid)); 605fc505c3ff6c1ba3a061e7e8b3f2236be90712a80Jeff Sharkey return StringPrintf("%s/media/%u", data.c_str(), userId); 606fc505c3ff6c1ba3a061e7e8b3f2236be90712a80Jeff Sharkey} 607fc505c3ff6c1ba3a061e7e8b3f2236be90712a80Jeff Sharkey 608be70c9ae2251ac8f3bfbbe75146f8c533d64e01bJeff Sharkeystd::string BuildDataUserCePath(const char* volumeUuid, userid_t userId) { 609d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey // TODO: unify with installd path generation logic 610d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey std::string data(BuildDataPath(volumeUuid)); 611d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey if (volumeUuid == nullptr) { 612d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey if (userId == 0) { 613d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey return StringPrintf("%s/data", data.c_str()); 614d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey } else { 615d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey return StringPrintf("%s/user/%u", data.c_str(), userId); 616d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey } 617d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey } else { 618d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey return StringPrintf("%s/user/%u", data.c_str(), userId); 619d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey } 620d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey} 621d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey 622d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkeystd::string BuildDataUserDePath(const char* volumeUuid, userid_t userId) { 623d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey // TODO: unify with installd path generation logic 624d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey std::string data(BuildDataPath(volumeUuid)); 625d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey return StringPrintf("%s/user_de/%u", data.c_str(), userId); 626d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey} 627d2c96e788381a6c8dd87cbf9ecd7e8a6bc7337c2Jeff Sharkey 62866270a21df1058434e4d63691221f11ff5387a0fJeff Sharkeydev_t GetDevice(const std::string& path) { 62966270a21df1058434e4d63691221f11ff5387a0fJeff Sharkey struct stat sb; 63066270a21df1058434e4d63691221f11ff5387a0fJeff Sharkey if (stat(path.c_str(), &sb)) { 63166270a21df1058434e4d63691221f11ff5387a0fJeff Sharkey PLOG(WARNING) << "Failed to stat " << path; 63266270a21df1058434e4d63691221f11ff5387a0fJeff Sharkey return 0; 63366270a21df1058434e4d63691221f11ff5387a0fJeff Sharkey } else { 63466270a21df1058434e4d63691221f11ff5387a0fJeff Sharkey return sb.st_dev; 63566270a21df1058434e4d63691221f11ff5387a0fJeff Sharkey } 63666270a21df1058434e4d63691221f11ff5387a0fJeff Sharkey} 63766270a21df1058434e4d63691221f11ff5387a0fJeff Sharkey 638d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkeystatus_t RestoreconRecursive(const std::string& path) { 639d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey LOG(VERBOSE) << "Starting restorecon of " << path; 640d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey 641d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey // TODO: find a cleaner way of waiting for restorecon to finish 642d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey const char* cpath = path.c_str(); 643d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey property_set("selinux.restorecon_recursive", ""); 644d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey property_set("selinux.restorecon_recursive", cpath); 645d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey 646d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey char value[PROPERTY_VALUE_MAX]; 647d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey while (true) { 648d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey property_get("selinux.restorecon_recursive", value, ""); 649d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey if (strcmp(cpath, value) == 0) { 650d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey break; 651d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey } 652d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey usleep(100000); // 100ms 653d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey } 654d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey 655d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey LOG(VERBOSE) << "Finished restorecon of " << path; 656d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey return OK; 657d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey} 658d24aeda425196a7ab0a19c00bc9a4ced6383432bJeff Sharkey 65910d34887b3e00e603604e0301487f9b8222c66f4Daichi Hironostatus_t SaneReadLinkAt(int dirfd, const char* path, char* buf, size_t bufsiz) { 66010d34887b3e00e603604e0301487f9b8222c66f4Daichi Hirono ssize_t len = readlinkat(dirfd, path, buf, bufsiz); 66110d34887b3e00e603604e0301487f9b8222c66f4Daichi Hirono if (len < 0) { 66210d34887b3e00e603604e0301487f9b8222c66f4Daichi Hirono return -1; 66310d34887b3e00e603604e0301487f9b8222c66f4Daichi Hirono } else if (len == (ssize_t) bufsiz) { 66410d34887b3e00e603604e0301487f9b8222c66f4Daichi Hirono return -1; 66510d34887b3e00e603604e0301487f9b8222c66f4Daichi Hirono } else { 66610d34887b3e00e603604e0301487f9b8222c66f4Daichi Hirono buf[len] = '\0'; 66710d34887b3e00e603604e0301487f9b8222c66f4Daichi Hirono return 0; 66810d34887b3e00e603604e0301487f9b8222c66f4Daichi Hirono } 66910d34887b3e00e603604e0301487f9b8222c66f4Daichi Hirono} 67010d34887b3e00e603604e0301487f9b8222c66f4Daichi Hirono 671942d4e830b2057177fd2d47c51b788edd6e94398Yu Ningbool IsRunningInEmulator() { 672942d4e830b2057177fd2d47c51b788edd6e94398Yu Ning return property_get_bool("ro.kernel.qemu", 0); 673942d4e830b2057177fd2d47c51b788edd6e94398Yu Ning} 674942d4e830b2057177fd2d47c51b788edd6e94398Yu Ning 675deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey} // namespace vold 676deb240573754daf36fa8ea10a05240f9f31e7b2cJeff Sharkey} // namespace android 677