2015-03-03 06:01:40 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2015 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 ANDROID_VOLD_UTILS_H
|
|
|
|
#define ANDROID_VOLD_UTILS_H
|
|
|
|
|
2017-08-01 18:15:53 +02:00
|
|
|
#include "KeyBuffer.h"
|
|
|
|
|
2017-09-13 19:49:44 +02:00
|
|
|
#include <android-base/macros.h>
|
2019-08-29 16:22:42 +02:00
|
|
|
#include <android-base/unique_fd.h>
|
2015-11-09 02:56:23 +01:00
|
|
|
#include <cutils/multiuser.h>
|
2015-04-01 20:54:32 +02:00
|
|
|
#include <selinux/selinux.h>
|
2018-09-18 22:30:21 +02:00
|
|
|
#include <utils/Errors.h>
|
2015-03-03 06:01:40 +01:00
|
|
|
|
2018-10-30 23:59:24 +01:00
|
|
|
#include <chrono>
|
2015-03-03 06:01:40 +01:00
|
|
|
#include <string>
|
2021-10-19 07:33:15 +02:00
|
|
|
#include <string_view>
|
2018-09-18 22:30:21 +02:00
|
|
|
#include <vector>
|
2015-03-03 06:01:40 +01:00
|
|
|
|
2016-01-29 06:33:51 +01:00
|
|
|
struct DIR;
|
|
|
|
|
2015-03-03 06:01:40 +01:00
|
|
|
namespace android {
|
|
|
|
namespace vold {
|
|
|
|
|
2020-02-11 15:31:24 +01:00
|
|
|
static const char* kVoldAppDataIsolationEnabled = "persist.sys.vold_app_data_isolation_enabled";
|
2020-05-12 07:58:42 +02:00
|
|
|
static const char* kExternalStorageSdcardfs = "external_storage.sdcardfs.enabled";
|
2021-10-13 13:03:18 +02:00
|
|
|
static const char* kFuseBpfEnabled = "persist.sys.fuse.bpf.enable";
|
2019-07-19 17:46:53 +02:00
|
|
|
|
2015-04-01 20:54:32 +02:00
|
|
|
/* SELinux contexts used depending on the block device type */
|
2021-09-10 10:51:08 +02:00
|
|
|
extern char* sBlkidContext;
|
|
|
|
extern char* sBlkidUntrustedContext;
|
|
|
|
extern char* sFsckContext;
|
|
|
|
extern char* sFsckUntrustedContext;
|
2015-04-01 20:54:32 +02:00
|
|
|
|
2017-10-20 17:07:53 +02:00
|
|
|
// TODO remove this with better solution, b/64143519
|
|
|
|
extern bool sSleepOnUnmount;
|
|
|
|
|
2020-06-12 13:59:45 +02:00
|
|
|
std::string GetFuseMountPathForUser(userid_t user_id, const std::string& relative_upper_path);
|
|
|
|
|
2015-03-03 06:01:40 +01:00
|
|
|
status_t CreateDeviceNode(const std::string& path, dev_t dev);
|
|
|
|
status_t DestroyDeviceNode(const std::string& path);
|
|
|
|
|
2021-02-01 08:57:02 +01:00
|
|
|
status_t SetDefaultAcl(const std::string& path, mode_t mode, uid_t uid, gid_t gid,
|
|
|
|
std::vector<gid_t> additionalGids);
|
|
|
|
|
2020-04-29 07:49:41 +02:00
|
|
|
status_t AbortFuseConnections();
|
|
|
|
|
2020-02-06 18:57:47 +01:00
|
|
|
int SetQuotaInherit(const std::string& path);
|
|
|
|
int SetQuotaProjectId(const std::string& path, long projectId);
|
2019-12-24 12:57:16 +01:00
|
|
|
/*
|
2020-02-10 23:48:11 +01:00
|
|
|
* Creates and sets up an application-specific path on external
|
|
|
|
* storage with the correct ACL and project ID (if needed).
|
2020-01-31 15:49:24 +01:00
|
|
|
*
|
2020-01-31 15:23:09 +01:00
|
|
|
* ONLY for use with app-specific data directories on external storage!
|
|
|
|
* (eg, /Android/data/com.foo, /Android/obb/com.foo, etc.)
|
2019-12-24 12:57:16 +01:00
|
|
|
*/
|
2020-02-18 15:06:37 +01:00
|
|
|
int PrepareAppDirFromRoot(const std::string& path, const std::string& root, int appUid,
|
|
|
|
bool fixupExisting);
|
2019-12-24 12:57:16 +01:00
|
|
|
|
2015-04-06 23:08:45 +02:00
|
|
|
/* fs_prepare_dir wrapper that creates with SELinux context */
|
2020-08-13 03:31:43 +02:00
|
|
|
status_t PrepareDir(const std::string& path, mode_t mode, uid_t uid, gid_t gid,
|
|
|
|
unsigned int attrs = 0);
|
2015-04-06 23:08:45 +02:00
|
|
|
|
2015-03-03 06:01:40 +01:00
|
|
|
/* Really unmounts the path, killing active processes along the way */
|
|
|
|
status_t ForceUnmount(const std::string& path);
|
|
|
|
|
2015-10-21 21:16:12 +02:00
|
|
|
/* Kills any processes using given path */
|
|
|
|
status_t KillProcessesUsingPath(const std::string& path);
|
|
|
|
|
2021-04-30 10:53:07 +02:00
|
|
|
/* Kills any processes using given tmpfs mount prifix */
|
|
|
|
status_t KillProcessesWithTmpfsMountPrefix(const std::string& path);
|
2020-02-11 15:31:24 +01:00
|
|
|
|
2015-03-14 00:09:20 +01:00
|
|
|
/* Creates bind mount from source to target */
|
|
|
|
status_t BindMount(const std::string& source, const std::string& target);
|
|
|
|
|
2019-02-06 21:39:19 +01:00
|
|
|
/** Creates a symbolic link to target */
|
|
|
|
status_t Symlink(const std::string& target, const std::string& linkpath);
|
|
|
|
|
|
|
|
/** Calls unlink(2) at linkpath */
|
|
|
|
status_t Unlink(const std::string& linkpath);
|
|
|
|
|
2019-02-14 20:09:51 +01:00
|
|
|
/** Creates the given directory if it is not already available */
|
|
|
|
status_t CreateDir(const std::string& dir, mode_t mode);
|
|
|
|
|
2017-10-07 02:02:53 +02:00
|
|
|
bool FindValue(const std::string& raw, const std::string& key, std::string* value);
|
|
|
|
|
2015-03-31 19:35:33 +02:00
|
|
|
/* Reads filesystem metadata from device at path */
|
2018-09-18 22:30:21 +02:00
|
|
|
status_t ReadMetadata(const std::string& path, std::string* fsType, std::string* fsUuid,
|
|
|
|
std::string* fsLabel);
|
2015-03-31 19:35:33 +02:00
|
|
|
|
2015-04-01 20:54:32 +02:00
|
|
|
/* Reads filesystem metadata from untrusted device at path */
|
2018-09-18 22:30:21 +02:00
|
|
|
status_t ReadMetadataUntrusted(const std::string& path, std::string* fsType, std::string* fsUuid,
|
|
|
|
std::string* fsLabel);
|
2015-04-01 20:54:32 +02:00
|
|
|
|
2015-04-09 06:07:21 +02:00
|
|
|
/* Returns either WEXITSTATUS() status, or a negative errno */
|
2021-09-10 10:51:08 +02:00
|
|
|
status_t ForkExecvp(const std::vector<std::string>& args,
|
|
|
|
std::vector<std::string>* output = nullptr, char* context = nullptr);
|
2015-03-31 19:35:33 +02:00
|
|
|
|
2015-04-25 01:00:03 +02:00
|
|
|
pid_t ForkExecvpAsync(const std::vector<std::string>& args);
|
|
|
|
|
2018-05-23 10:50:46 +02:00
|
|
|
/* Gets block device size in bytes */
|
|
|
|
status_t GetBlockDevSize(int fd, uint64_t* size);
|
|
|
|
status_t GetBlockDevSize(const std::string& path, uint64_t* size);
|
|
|
|
/* Gets block device size in 512 byte sectors */
|
|
|
|
status_t GetBlockDev512Sectors(const std::string& path, uint64_t* nr_sec);
|
|
|
|
|
2015-03-31 19:35:33 +02:00
|
|
|
status_t ReadRandomBytes(size_t bytes, std::string& out);
|
2017-08-01 18:15:53 +02:00
|
|
|
status_t ReadRandomBytes(size_t bytes, char* buffer);
|
Progress towards FBE and adoptable storage.
Offer to adopt storage devices on FBE devices, but keep it guarded
behind a system property for now, since we still need to work out key
storage details.
When migrating shared storage, leave user-specific /data/media
directories in place, since they already have the needed crypto
policies defined.
Enable journaling, quotas, and encrypt options when formatting
newly adopted devices. installd already gracefully handles older
partitions without quota enabled.
Test: cts-tradefed run commandAndExit cts-dev --abi armeabi-v7a -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.AdoptableHostTest
Bug: 62290006, 36757864, 29117062, 37395736
Bug: 29923055, 25861755, 30230655, 37436961
Change-Id: Ibbeb6ec9db2394a279bbac221a2b20711d65494e
2017-06-21 21:52:23 +02:00
|
|
|
status_t GenerateRandomUuid(std::string& out);
|
2015-03-31 19:35:33 +02:00
|
|
|
|
2015-04-01 20:54:32 +02:00
|
|
|
/* Converts hex string to raw bytes, ignoring [ :-] */
|
2015-03-31 19:35:33 +02:00
|
|
|
status_t HexToStr(const std::string& hex, std::string& str);
|
2015-04-01 20:54:32 +02:00
|
|
|
/* Converts raw bytes to hex string */
|
2015-03-31 19:35:33 +02:00
|
|
|
status_t StrToHex(const std::string& str, std::string& hex);
|
2017-08-01 18:15:53 +02:00
|
|
|
/* Converts raw key bytes to hex string */
|
|
|
|
status_t StrToHex(const KeyBuffer& str, KeyBuffer& hex);
|
2015-06-18 23:25:08 +02:00
|
|
|
/* Normalize given hex string into consistent format */
|
|
|
|
status_t NormalizeHex(const std::string& in, std::string& out);
|
2015-03-31 19:35:33 +02:00
|
|
|
|
2015-04-25 01:00:03 +02:00
|
|
|
uint64_t GetFreeBytes(const std::string& path);
|
|
|
|
uint64_t GetTreeBytes(const std::string& path);
|
|
|
|
|
2015-05-22 07:35:42 +02:00
|
|
|
bool IsFilesystemSupported(const std::string& fsType);
|
2020-05-12 07:58:42 +02:00
|
|
|
bool IsSdcardfsUsed();
|
2020-02-11 15:31:24 +01:00
|
|
|
bool IsFuseDaemon(const pid_t pid);
|
2015-05-22 07:35:42 +02:00
|
|
|
|
|
|
|
/* Wipes contents of block device at given path */
|
|
|
|
status_t WipeBlockDevice(const std::string& path);
|
|
|
|
|
2015-06-18 23:25:08 +02:00
|
|
|
std::string BuildKeyPath(const std::string& partGuid);
|
|
|
|
|
2016-04-15 04:45:16 +02:00
|
|
|
std::string BuildDataSystemLegacyPath(userid_t userid);
|
2015-11-09 02:56:23 +01:00
|
|
|
std::string BuildDataSystemCePath(userid_t userid);
|
2016-02-02 01:02:29 +01:00
|
|
|
std::string BuildDataSystemDePath(userid_t userid);
|
2016-04-15 04:45:16 +02:00
|
|
|
std::string BuildDataMiscLegacyPath(userid_t userid);
|
2016-02-02 01:02:29 +01:00
|
|
|
std::string BuildDataMiscCePath(userid_t userid);
|
|
|
|
std::string BuildDataMiscDePath(userid_t userid);
|
2016-02-17 21:14:46 +01:00
|
|
|
std::string BuildDataProfilesDePath(userid_t userid);
|
2018-01-22 20:25:29 +01:00
|
|
|
std::string BuildDataVendorCePath(userid_t userid);
|
|
|
|
std::string BuildDataVendorDePath(userid_t userid);
|
2015-11-09 02:56:23 +01:00
|
|
|
|
2017-10-09 19:55:21 +02:00
|
|
|
std::string BuildDataPath(const std::string& volumeUuid);
|
|
|
|
std::string BuildDataMediaCePath(const std::string& volumeUuid, userid_t userid);
|
|
|
|
std::string BuildDataUserCePath(const std::string& volumeUuid, userid_t userid);
|
|
|
|
std::string BuildDataUserDePath(const std::string& volumeUuid, userid_t userid);
|
2015-11-09 02:56:23 +01:00
|
|
|
|
2015-06-24 20:49:24 +02:00
|
|
|
dev_t GetDevice(const std::string& path);
|
|
|
|
|
2020-11-06 04:58:26 +01:00
|
|
|
bool IsSameFile(const std::string& path1, const std::string& path2);
|
|
|
|
|
2020-02-11 15:31:24 +01:00
|
|
|
status_t EnsureDirExists(const std::string& path, mode_t mode, uid_t uid, gid_t gid);
|
|
|
|
|
2016-07-16 00:20:22 +02:00
|
|
|
status_t RestoreconRecursive(const std::string& path);
|
|
|
|
|
2017-10-07 02:02:53 +02:00
|
|
|
// TODO: promote to android::base
|
|
|
|
bool Readlinkat(int dirfd, const std::string& path, std::string* result);
|
2016-01-29 06:33:51 +01:00
|
|
|
|
2020-05-15 01:35:03 +02:00
|
|
|
// Handles dynamic major assignment for virtio-block
|
|
|
|
bool IsVirtioBlkDevice(unsigned int major);
|
2016-01-08 10:36:47 +01:00
|
|
|
|
2019-01-17 08:04:07 +01:00
|
|
|
status_t UnmountTreeWithPrefix(const std::string& prefix);
|
|
|
|
status_t UnmountTree(const std::string& mountPoint);
|
2018-09-25 23:22:07 +02:00
|
|
|
|
2020-11-03 00:31:56 +01:00
|
|
|
bool IsDotOrDotDot(const struct dirent& ent);
|
|
|
|
|
2018-09-18 22:07:45 +02:00
|
|
|
status_t DeleteDirContentsAndDir(const std::string& pathname);
|
2019-02-23 02:03:02 +01:00
|
|
|
status_t DeleteDirContents(const std::string& pathname);
|
2018-09-18 22:07:45 +02:00
|
|
|
|
2018-10-30 23:59:24 +01:00
|
|
|
status_t WaitForFile(const char* filename, std::chrono::nanoseconds timeout);
|
|
|
|
|
2021-02-17 00:59:17 +01:00
|
|
|
bool pathExists(const std::string& path);
|
|
|
|
|
2018-12-08 00:36:09 +01:00
|
|
|
bool FsyncDirectory(const std::string& dirname);
|
|
|
|
|
2021-02-17 00:59:17 +01:00
|
|
|
bool FsyncParentDirectory(const std::string& path);
|
|
|
|
|
2021-02-17 00:59:17 +01:00
|
|
|
bool MkdirsSync(const std::string& path, mode_t mode);
|
|
|
|
|
2019-03-26 10:18:09 +01:00
|
|
|
bool writeStringToFile(const std::string& payload, const std::string& filename);
|
2019-07-19 17:46:53 +02:00
|
|
|
|
2020-06-29 11:53:34 +02:00
|
|
|
void ConfigureMaxDirtyRatioForFuse(const std::string& fuse_mount, unsigned int max_ratio);
|
|
|
|
|
2020-06-12 13:59:45 +02:00
|
|
|
void ConfigureReadAheadForFuse(const std::string& fuse_mount, size_t read_ahead_kb);
|
|
|
|
|
2019-09-25 15:37:38 +02:00
|
|
|
status_t MountUserFuse(userid_t user_id, const std::string& absolute_lower_path,
|
|
|
|
const std::string& relative_upper_path, android::base::unique_fd* fuse_fd);
|
|
|
|
|
2019-11-28 11:53:53 +01:00
|
|
|
status_t UnmountUserFuse(userid_t userId, const std::string& absolute_lower_path,
|
|
|
|
const std::string& relative_upper_path);
|
2019-07-19 17:46:53 +02:00
|
|
|
|
2020-01-31 15:23:09 +01:00
|
|
|
status_t PrepareAndroidDirs(const std::string& volumeRoot);
|
2021-10-19 07:33:15 +02:00
|
|
|
|
|
|
|
// Open a given directory as an FD, and return that and the corresponding procfs virtual
|
|
|
|
// symlink path that can be used in any API that accepts a path string. Path stays valid until
|
|
|
|
// the directory FD is closed.
|
|
|
|
//
|
|
|
|
// This may be useful when an API wants to restrict a path passed from an untrusted process,
|
|
|
|
// and do it without any TOCTOU attacks possible (e.g. where an attacker replaces one of
|
|
|
|
// the components with a symlink after the check passed). In that case opening a path through
|
|
|
|
// this function guarantees that the target directory stays the same, and that it can be
|
|
|
|
// referenced inside the current process via the virtual procfs symlink returned here.
|
|
|
|
std::pair<android::base::unique_fd, std::string> OpenDirInProcfs(std::string_view path);
|
|
|
|
|
2015-03-03 06:01:40 +01:00
|
|
|
} // namespace vold
|
|
|
|
} // namespace android
|
|
|
|
|
|
|
|
#endif
|