diff options
Diffstat (limited to 'ext4_utils')
-rw-r--r-- | ext4_utils/Android.mk | 9 | ||||
-rw-r--r-- | ext4_utils/allocate.c | 2 | ||||
-rw-r--r-- | ext4_utils/ext4_crypt.cpp | 152 | ||||
-rw-r--r-- | ext4_utils/ext4_crypt.h | 30 | ||||
-rw-r--r-- | ext4_utils/ext4_crypt_init_extensions.cpp | 185 | ||||
-rw-r--r-- | ext4_utils/ext4_crypt_init_extensions.h | 21 | ||||
-rw-r--r-- | ext4_utils/make_ext4fs.c | 25 | ||||
-rw-r--r-- | ext4_utils/make_ext4fs.h | 6 | ||||
-rw-r--r-- | ext4_utils/unencrypted_properties.cpp | 99 | ||||
-rw-r--r-- | ext4_utils/unencrypted_properties.h | 74 |
10 files changed, 260 insertions, 343 deletions
diff --git a/ext4_utils/Android.mk b/ext4_utils/Android.mk index 15abf73c..babf5ca5 100644 --- a/ext4_utils/Android.mk +++ b/ext4_utils/Android.mk @@ -55,8 +55,7 @@ include $(BUILD_HOST_EXECUTABLE) libext4_utils_src_files += \ key_control.cpp \ - ext4_crypt.cpp \ - unencrypted_properties.cpp + ext4_crypt.cpp ifneq ($(HOST_OS),windows) @@ -67,6 +66,7 @@ LOCAL_C_INCLUDES += system/core/logwrapper/include # Various instances of dereferencing a type-punned pointer in extent.c LOCAL_CFLAGS += -fno-strict-aliasing LOCAL_SHARED_LIBRARIES := \ + libbase \ libcutils \ libext2_uuid \ libselinux \ @@ -83,8 +83,11 @@ LOCAL_MODULE := libext4_utils_static # Various instances of dereferencing a type-punned pointer in extent.c LOCAL_CFLAGS += -fno-strict-aliasing LOCAL_STATIC_LIBRARIES := \ + libbase \ + liblogwrap \ libsparse_static \ - libselinux + libselinux \ + libbase include $(BUILD_STATIC_LIBRARY) diff --git a/ext4_utils/allocate.c b/ext4_utils/allocate.c index cca3dc13..d18aec56 100644 --- a/ext4_utils/allocate.c +++ b/ext4_utils/allocate.c @@ -307,7 +307,7 @@ static void init_bg(struct block_group_info *bg, unsigned int i) bg->first_free_block = 0; bg->free_inodes = info.inodes_per_group; bg->first_free_inode = 1; - bg->flags = EXT4_BG_INODE_UNINIT; + bg->flags = 0; if (reserve_blocks(bg, bg->first_free_block, bg->header_blocks) < 0) error("failed to reserve %u blocks in block group %u\n", bg->header_blocks, i); diff --git a/ext4_utils/ext4_crypt.cpp b/ext4_utils/ext4_crypt.cpp index 886d17a1..37e17c5c 100644 --- a/ext4_utils/ext4_crypt.cpp +++ b/ext4_utils/ext4_crypt.cpp @@ -2,9 +2,7 @@ * Copyright (c) 2015 Google, Inc. */ -#define TAG "ext4_utils" - -#include "ext4_crypt_init_extensions.h" +#include "ext4_crypt.h" #include <dirent.h> #include <errno.h> @@ -17,9 +15,7 @@ #include <sys/stat.h> #include <sys/types.h> -#include <cutils/klog.h> - -#include "unencrypted_properties.h" +#include <android-base/logging.h> #define XATTR_NAME_ENCRYPTION_POLICY "encryption.policy" #define EXT4_KEYREF_DELIMITER ((char)'.') @@ -27,6 +23,8 @@ // ext4enc:TODO Include structure from somewhere sensible // MUST be in sync with ext4_crypto.c in kernel #define EXT4_KEY_DESCRIPTOR_SIZE 8 +#define EXT4_KEY_DESCRIPTOR_SIZE_HEX 17 + struct ext4_encryption_policy { char version; char contents_encryption_mode; @@ -39,18 +37,17 @@ struct ext4_encryption_policy { #define EXT4_ENCRYPTION_MODE_AES_256_CTS 4 // ext4enc:TODO Get value from somewhere sensible -#define EXT4_IOC_SET_ENCRYPTION_POLICY \ - _IOR('f', 19, struct ext4_encryption_policy) +#define EXT4_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct ext4_encryption_policy) +#define EXT4_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct ext4_encryption_policy) -/* Validate that all path items are available and accessible. */ -static int is_path_valid(const char *path) -{ - if (access(path, W_OK)) { - KLOG_ERROR(TAG, "Can't access %s: %s\n",strerror(errno), path); - return 0; - } +#define HEX_LOOKUP "0123456789abcdef" - return 1; +static void policy_to_hex(const char* policy, char* hex) { + for (size_t i = 0, j = 0; i < EXT4_KEY_DESCRIPTOR_SIZE; i++) { + hex[j++] = HEX_LOOKUP[(policy[i] & 0xF0) >> 4]; + hex[j++] = HEX_LOOKUP[policy[i] & 0x0F]; + } + hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX - 1] = '\0'; } static int is_dir_empty(const char *dirname) @@ -71,36 +68,26 @@ static int is_dir_empty(const char *dirname) return n <= 2; } -int do_policy_set(const char *directory, const char *policy, int policy_length) -{ - struct stat st; - ssize_t ret; - +int e4crypt_policy_set(const char *directory, const char *policy, size_t policy_length) { if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) { - KLOG_ERROR("Policy wrong length\n"); - return -EINVAL; + LOG(ERROR) << "Policy wrong length: " << policy_length; + return -1; } - if (!is_path_valid(directory)) { - return -EINVAL; + if (access(directory, W_OK)) { + PLOG(ERROR) << "Failed to access directory " << directory; + return -1; } - stat(directory, &st); - if (!S_ISDIR(st.st_mode)) { - KLOG_ERROR(TAG, "Can only set policy on a directory (%s)\n", directory); - return -EINVAL; + int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); + if (fd == -1) { + PLOG(ERROR) << "Failed to open directory " << directory; + return -1; } if (!is_dir_empty(directory)) { - KLOG_ERROR(TAG, "Can only set policy on an empty directory (%s)\n", - directory); - return -EINVAL; - } - - int fd = open(directory, O_DIRECTORY); - if (fd == -1) { - KLOG_ERROR(TAG, "Failed to open directory (%s)\n", directory); - return -EINVAL; + LOG(ERROR) << "Can only set policy on an empty directory " << directory; + return -1; } ext4_encryption_policy eep; @@ -109,23 +96,84 @@ int do_policy_set(const char *directory, const char *policy, int policy_length) eep.filenames_encryption_mode = EXT4_ENCRYPTION_MODE_AES_256_CTS; eep.flags = 0; memcpy(eep.master_key_descriptor, policy, EXT4_KEY_DESCRIPTOR_SIZE); - ret = ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, &eep); - auto preserve_errno = errno; - close(fd); - - if (ret) { - KLOG_ERROR(TAG, "Failed to set encryption policy for %s: %s\n", - directory, strerror(preserve_errno)); - return -EINVAL; + if (ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, &eep)) { + PLOG(ERROR) << "Failed to set encryption policy for " << directory; + close(fd); + return -1; + } else { + close(fd); } - KLOG_INFO(TAG, "Encryption policy for %s is set to %02x%02x%02x%02x\n", - directory, policy[0], policy[1], policy[2], policy[3]); + char policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX]; + policy_to_hex(policy, policy_hex); + LOG(INFO) << "Policy for " << directory << " set to " << policy_hex; return 0; } -bool e4crypt_non_default_key(const char* dir) -{ - UnencryptedProperties props(dir); - return props.Get<int>(properties::is_default, 1) != 1; +int e4crypt_policy_get(const char *directory, char *policy, size_t policy_length) { + if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) { + LOG(ERROR) << "Policy wrong length: " << policy_length; + return -1; + } + + if (access(directory, W_OK)) { + PLOG(ERROR) << "Failed to access directory " << directory; + return -1; + } + + int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); + if (fd == -1) { + PLOG(ERROR) << "Failed to open directory " << directory; + return -1; + } + + ext4_encryption_policy eep; + memset(&eep, 0, sizeof(ext4_encryption_policy)); + + if (ioctl(fd, EXT4_IOC_GET_ENCRYPTION_POLICY, &eep)) { + PLOG(WARNING) << "Failed to get encryption policy for " << directory; + close(fd); + return -1; + } else { + close(fd); + } + + if ((eep.version == 0) + && (eep.contents_encryption_mode == EXT4_ENCRYPTION_MODE_AES_256_XTS) + && (eep.filenames_encryption_mode == EXT4_ENCRYPTION_MODE_AES_256_CTS) + && (eep.flags == 0)) { + memcpy(policy, eep.master_key_descriptor, EXT4_KEY_DESCRIPTOR_SIZE); + return 0; + } + + LOG(ERROR) << "Failed to find matching encryption policy for " << directory; + return -1; +} + +int e4crypt_policy_ensure(const char *directory, const char *policy, size_t policy_length) { + if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) { + LOG(ERROR) << "Policy wrong length: " << policy_length; + return -1; + } + + char existing_policy[EXT4_KEY_DESCRIPTOR_SIZE]; + if (e4crypt_policy_get(directory, existing_policy, EXT4_KEY_DESCRIPTOR_SIZE) == 0) { + char policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX]; + char existing_policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX]; + + policy_to_hex(policy, policy_hex); + policy_to_hex(existing_policy, existing_policy_hex); + + if (memcmp(policy, existing_policy, EXT4_KEY_DESCRIPTOR_SIZE) == 0) { + LOG(INFO) << "Found policy " << existing_policy_hex << " at " << directory + << " which matches expected value"; + return 0; + } else { + LOG(ERROR) << "Found policy " << existing_policy_hex << " at " << directory + << " which doesn't match expected value " << policy_hex; + return -1; + } + } + + return e4crypt_policy_set(directory, policy, policy_length); } diff --git a/ext4_utils/ext4_crypt.h b/ext4_utils/ext4_crypt.h new file mode 100644 index 00000000..4eb74e29 --- /dev/null +++ b/ext4_utils/ext4_crypt.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2016 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 <sys/cdefs.h> +#include <stdbool.h> +#include <cutils/multiuser.h> + +__BEGIN_DECLS + +int e4crypt_policy_get(const char *directory, char* policy, size_t policy_length); +int e4crypt_policy_set(const char *directory, const char* policy, size_t policy_length); +int e4crypt_policy_ensure(const char *directory, const char* policy, size_t policy_length); + +static const char* e4crypt_unencrypted_folder = "/unencrypted"; +static const char* e4crypt_key_ref = "/unencrypted/ref"; + +__END_DECLS diff --git a/ext4_utils/ext4_crypt_init_extensions.cpp b/ext4_utils/ext4_crypt_init_extensions.cpp index 64ec330c..dc6e1dc7 100644 --- a/ext4_utils/ext4_crypt_init_extensions.cpp +++ b/ext4_utils/ext4_crypt_init_extensions.cpp @@ -1,8 +1,28 @@ +/* + * Copyright (C) 2016 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. + */ + #define TAG "ext4_utils" #include "ext4_crypt_init_extensions.h" +#include "ext4_crypt.h" + +#include <android-base/logging.h> #include <string> +#include <vector> #include <dirent.h> #include <errno.h> @@ -10,116 +30,57 @@ #include <sys/stat.h> #include <unistd.h> +#include <android-base/file.h> + #include <cutils/klog.h> #include <cutils/properties.h> #include <cutils/sockets.h> -#include <poll.h> +#include <logwrap/logwrap.h> #include "key_control.h" -#include "unencrypted_properties.h" static const std::string arbitrary_sequence_number = "42"; static const int vold_command_timeout_ms = 60 * 1000; -static std::string vold_command(std::string const& command) -{ - KLOG_INFO(TAG, "Running command %s\n", command.c_str()); - int sock = -1; - - while (true) { - sock = socket_local_client("cryptd", - ANDROID_SOCKET_NAMESPACE_RESERVED, - SOCK_STREAM); - if (sock >= 0) { - break; - } - usleep(10000); - } - - if (sock < 0) { - KLOG_INFO(TAG, "Cannot open vold, failing command (%s)\n", strerror(errno)); - return ""; - } - - class CloseSocket - { - int sock_; - public: - CloseSocket(int sock) : sock_(sock) {} - ~CloseSocket() { close(sock_); } - }; - - CloseSocket cs(sock); - - // Use arbitrary sequence number. This should only be used when the - // framework is down, so this is (mostly) OK. - std::string actual_command = arbitrary_sequence_number + " " + command; - if (write(sock, actual_command.c_str(), actual_command.size() + 1) < 0) { - KLOG_ERROR(TAG, "Cannot write command (%s)\n", strerror(errno)); - return ""; - } - - struct pollfd poll_sock = {sock, POLLIN, 0}; - - int rc = TEMP_FAILURE_RETRY(poll(&poll_sock, 1, vold_command_timeout_ms)); - if (rc < 0) { - KLOG_ERROR(TAG, "Error in poll (%s)\n", strerror(errno)); - return ""; - } - - if (!(poll_sock.revents & POLLIN)) { - KLOG_ERROR(TAG, "Timeout\n"); - return ""; - } - char buffer[4096]; - memset(buffer, 0, sizeof(buffer)); - rc = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer))); - if (rc <= 0) { - if (rc == 0) { - KLOG_ERROR(TAG, "Lost connection to Vold - did it crash?\n"); - } else { - KLOG_ERROR(TAG, "Error reading data (%s)\n", strerror(errno)); - } - return ""; +static void kernel_logger(android::base::LogId, android::base::LogSeverity severity, const char*, + const char*, unsigned int, const char* message) { + if (severity == android::base::ERROR || severity == android::base::FATAL) { + KLOG_ERROR(TAG, "%s\n", message); + } else if (severity == android::base::WARNING) { + KLOG_WARNING(TAG, "%s\n", message); + } else { + KLOG_INFO(TAG, "%s\n", message); } +} - // We don't truly know that this is the correct result. However, - // since this will only be used when the framework is down, - // it should be OK unless someone is running vdc at the same time. - // Worst case we force a reboot in the very rare synchronization - // error - return std::string(buffer, rc); +static void init_logging() { + android::base::SetLogger(kernel_logger); } int e4crypt_create_device_key(const char* dir, int ensure_dir_exists(const char*)) { - // Already encrypted with password? If so bail - std::string temp_folder = std::string() + dir + "/tmp_mnt"; - DIR* temp_dir = opendir(temp_folder.c_str()); - if (temp_dir) { - closedir(temp_dir); - return 0; - } + init_logging(); // Make sure folder exists. Use make_dir to set selinux permissions. - if (ensure_dir_exists(UnencryptedProperties::GetPath(dir).c_str())) { + std::string unencrypted_dir = std::string(dir) + "/unencrypted"; + if (ensure_dir_exists(unencrypted_dir.c_str())) { KLOG_ERROR(TAG, "Failed to create %s (%s)\n", - UnencryptedProperties::GetPath(dir).c_str(), + unencrypted_dir.c_str(), strerror(errno)); return -1; } - auto result = vold_command("cryptfs enablefilecrypto"); - // ext4enc:TODO proper error handling - KLOG_INFO(TAG, "enablefilecrypto returned with result %s\n", - result.c_str()); - - return 0; + const char* argv[] = { "/system/bin/vdc", "--wait", "cryptfs", "enablefilecrypto" }; + int rc = android_fork_execvp(4, (char**) argv, NULL, false, true); + LOG(INFO) << "enablefilecrypto result: " << rc; + return rc; } int e4crypt_install_keyring() { + init_logging(); + key_serial_t device_keyring = add_key("keyring", "e4crypt", 0, 0, KEY_SPEC_SESSION_KEYRING); @@ -128,14 +89,26 @@ int e4crypt_install_keyring() return -1; } - KLOG_INFO(TAG, "Keyring created wth id %d in process %d\n", + KLOG_INFO(TAG, "Keyring created with id %d in process %d\n", device_keyring, getpid()); return 0; } +int e4crypt_do_init_user0() +{ + init_logging(); + + const char* argv[] = { "/system/bin/vdc", "--wait", "cryptfs", "init_user0" }; + int rc = android_fork_execvp(4, (char**) argv, NULL, false, true); + LOG(INFO) << "init_user0 result: " << rc; + return rc; +} + int e4crypt_set_directory_policy(const char* dir) { + init_logging(); + // Only set policy on first level /data directories // To make this less restrictive, consider using a policy file. // However this is overkill for as long as the policy is simply @@ -144,25 +117,33 @@ int e4crypt_set_directory_policy(const char* dir) return 0; } - // Don't encrypt lost+found - ext4 doesn't like it - if (!strcmp(dir, "/data/lost+found")) { - return 0; - } - - // ext4enc:TODO exclude /data/user with a horrible special case. - if (!strcmp(dir, "/data/user")) { - return 0; + // Special case various directories that must not be encrypted, + // often because their subdirectories must be encrypted. + // This isn't a nice way to do this, see b/26641735 + std::vector<std::string> directories_to_exclude = { + "lost+found", + "system_ce", "system_de", + "misc_ce", "misc_de", + "media", + "data", "user", "user_de", + }; + std::string prefix = "/data/"; + for (auto d: directories_to_exclude) { + if ((prefix + d) == dir) { + KLOG_INFO(TAG, "Not setting policy on %s\n", dir); + return 0; + } } - UnencryptedProperties props("/data"); - std::string policy = props.Get<std::string>(properties::ref); - if (policy.empty()) { - // ext4enc:TODO why is this OK? + std::string ref_filename = std::string("/data") + e4crypt_key_ref; + std::string policy; + if (!android::base::ReadFileToString(ref_filename, &policy)) { + KLOG_INFO(TAG, "Not file encrypted so no policy for %s\n", dir); return 0; } KLOG_INFO(TAG, "Setting policy on %s\n", dir); - int result = do_policy_set(dir, policy.c_str(), policy.size()); + int result = e4crypt_policy_ensure(dir, policy.c_str(), policy.size()); if (result) { KLOG_ERROR(TAG, "Setting %02x%02x%02x%02x policy on %s failed!\n", policy[0], policy[1], policy[2], policy[3], dir); @@ -171,13 +152,3 @@ int e4crypt_set_directory_policy(const char* dir) return 0; } - -int e4crypt_set_user_crypto_policies(const char* dir) -{ - auto command = std::string() + "cryptfs setusercryptopolicies " + dir; - auto result = vold_command(command); - // ext4enc:TODO proper error handling - KLOG_INFO(TAG, "setusercryptopolicies returned with result %s\n", - result.c_str()); - return 0; -} diff --git a/ext4_utils/ext4_crypt_init_extensions.h b/ext4_utils/ext4_crypt_init_extensions.h index d02d181d..63f6d88c 100644 --- a/ext4_utils/ext4_crypt_init_extensions.h +++ b/ext4_utils/ext4_crypt_init_extensions.h @@ -1,5 +1,22 @@ +/* + * Copyright (C) 2016 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 <sys/cdefs.h> #include <stdbool.h> +#include <cutils/multiuser.h> __BEGIN_DECLS @@ -9,8 +26,6 @@ int e4crypt_install_keyring(); int e4crypt_create_device_key(const char* path, int ensure_dir_exists(const char* dir)); int e4crypt_set_directory_policy(const char* path); -bool e4crypt_non_default_key(const char* path); -int do_policy_set(const char *directory, const char *policy, int policy_length); -int e4crypt_set_user_crypto_policies(const char* path); +int e4crypt_do_init_user0(); __END_DECLS diff --git a/ext4_utils/make_ext4fs.c b/ext4_utils/make_ext4fs.c index 1ba415bd..913a40df 100644 --- a/ext4_utils/make_ext4fs.c +++ b/ext4_utils/make_ext4fs.c @@ -414,15 +414,31 @@ void reset_ext4fs_info() { int make_ext4fs_sparse_fd(int fd, long long len, const char *mountpoint, struct selabel_handle *sehnd) { + return make_ext4fs_sparse_fd_directory(fd, len, mountpoint, sehnd, NULL); +} + +int make_ext4fs_sparse_fd_directory(int fd, long long len, + const char *mountpoint, struct selabel_handle *sehnd, + const char *directory) +{ reset_ext4fs_info(); info.len = len; - return make_ext4fs_internal(fd, NULL, NULL, mountpoint, NULL, 0, 1, 0, 0, 0, sehnd, 0, -1, NULL); + return make_ext4fs_internal(fd, directory, NULL, mountpoint, NULL, + 0, 1, 0, 0, 0, + sehnd, 0, -1, NULL); } int make_ext4fs(const char *filename, long long len, const char *mountpoint, struct selabel_handle *sehnd) { + return make_ext4fs_directory(filename, len, mountpoint, sehnd, NULL); +} + +int make_ext4fs_directory(const char *filename, long long len, + const char *mountpoint, struct selabel_handle *sehnd, + const char *directory) +{ int fd; int status; @@ -435,7 +451,9 @@ int make_ext4fs(const char *filename, long long len, return EXIT_FAILURE; } - status = make_ext4fs_internal(fd, NULL, NULL, mountpoint, NULL, 0, 0, 0, 1, 0, sehnd, 0, -1, NULL); + status = make_ext4fs_internal(fd, directory, NULL, mountpoint, NULL, + 0, 0, 0, 1, 0, + sehnd, 0, -1, NULL); close(fd); return status; @@ -579,8 +597,7 @@ int make_ext4fs_internal(int fd, const char *_directory, const char *_target_out info.feat_ro_compat |= EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER | - EXT4_FEATURE_RO_COMPAT_LARGE_FILE | - EXT4_FEATURE_RO_COMPAT_GDT_CSUM; + EXT4_FEATURE_RO_COMPAT_LARGE_FILE; info.feat_incompat |= EXT4_FEATURE_INCOMPAT_EXTENTS | diff --git a/ext4_utils/make_ext4fs.h b/ext4_utils/make_ext4fs.h index 3784a9ea..4498e628 100644 --- a/ext4_utils/make_ext4fs.h +++ b/ext4_utils/make_ext4fs.h @@ -25,8 +25,14 @@ struct selabel_handle; int make_ext4fs(const char *filename, long long len, const char *mountpoint, struct selabel_handle *sehnd); +int make_ext4fs_directory(const char *filename, long long len, + const char *mountpoint, struct selabel_handle *sehnd, + const char *directory); int make_ext4fs_sparse_fd(int fd, long long len, const char *mountpoint, struct selabel_handle *sehnd); +int make_ext4fs_sparse_fd_directory(int fd, long long len, + const char *mountpoint, struct selabel_handle *sehnd, + const char *directory); #ifdef __cplusplus } diff --git a/ext4_utils/unencrypted_properties.cpp b/ext4_utils/unencrypted_properties.cpp deleted file mode 100644 index ed36e206..00000000 --- a/ext4_utils/unencrypted_properties.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include "unencrypted_properties.h" - -#include <sys/stat.h> -#include <dirent.h> - -namespace properties { - const char* key = "key"; - const char* ref = "ref"; - const char* props = "props"; - const char* is_default = "is_default"; -} - -namespace -{ - const char* unencrypted_folder = "unencrypted"; -} - -std::string UnencryptedProperties::GetPath(const char* device) -{ - return std::string() + device + "/" + unencrypted_folder; -} - -UnencryptedProperties::UnencryptedProperties(const char* device) - : folder_(GetPath(device)) -{ - DIR* dir = opendir(folder_.c_str()); - if (dir) { - closedir(dir); - } else { - folder_.clear(); - } -} - -UnencryptedProperties::UnencryptedProperties() -{ -} - -template<> std::string UnencryptedProperties::Get(const char* name, - std::string default_value) const -{ - if (!OK()) return default_value; - std::ifstream i(folder_ + "/" + name, std::ios::binary); - if (!i) { - return default_value; - } - - i.seekg(0, std::ios::end); - int length = i.tellg(); - i.seekg(0, std::ios::beg); - if (length == -1) { - return default_value; - } - - std::string s(length, 0); - i.read(&s[0], length); - if (!i) { - return default_value; - } - - return s; -} - -template<> bool UnencryptedProperties::Set(const char* name, std::string const& value) -{ - if (!OK()) return false; - std::ofstream o(folder_ + "/" + name, std::ios::binary); - o << value; - return !o.fail(); -} - -UnencryptedProperties UnencryptedProperties::GetChild(const char* name) const -{ - UnencryptedProperties up; - if (!OK()) return up; - - std::string directory(folder_ + "/" + name); - if (mkdir(directory.c_str(), 700) == -1 && errno != EEXIST) { - return up; - } - - up.folder_ = directory; - return up; -} - -bool UnencryptedProperties::Remove(const char* name) -{ - if (!OK()) return false; - if (remove((folder_ + "/" + name).c_str()) - && errno != ENOENT) { - return false; - } - - return true; -} - -bool UnencryptedProperties::OK() const -{ - return !folder_.empty(); -} diff --git a/ext4_utils/unencrypted_properties.h b/ext4_utils/unencrypted_properties.h deleted file mode 100644 index b2d1295f..00000000 --- a/ext4_utils/unencrypted_properties.h +++ /dev/null @@ -1,74 +0,0 @@ -#include <string> -#include <fstream> - -// key names for properties we use -namespace properties { - extern const char* key; - extern const char* ref; - extern const char* props; - extern const char* is_default; -} - -/** - * Class to store data on the unencrypted folder of a device. - * Note that the folder must exist before this class is constructed. - * All names must be valid single level (no '/') file or directory names - * Data is organized hierarchically so we can get a child folder - */ -class UnencryptedProperties -{ -public: - // Get path of folder. Must create before using any properties - // This is to allow proper setting of SELinux policy - static std::string GetPath(const char* device); - - // Opens properties folder on named device. - // If folder does not exist, OK will return false, all - // getters will return default properties and setters will fail. - UnencryptedProperties(const char* device); - - // Get named object. Return default if object does not exist or error. - template<typename t> t Get(const char* name, t default_value = t()) const; - - // Set named object. Return true if success, false otherwise - template<typename t> bool Set(const char* name, t const& value); - - // Get child properties - UnencryptedProperties GetChild(const char* name) const; - - // Remove named object - bool Remove(const char* name); - - // Does folder exist? - bool OK() const; - -private: - UnencryptedProperties(); - std::string folder_; -}; - - -template<typename t> t UnencryptedProperties::Get(const char* name, - t default_value) const -{ - if (!OK()) return default_value; - t value = default_value; - std::ifstream(folder_ + "/" + name) >> value; - return value; -} - -template<typename t> bool UnencryptedProperties::Set(const char* name, - t const& value) -{ - if (!OK()) return false; - std::ofstream o(folder_ + "/" + name); - o << value; - return !o.fail(); -} - -// Specialized getters/setters for strings -template<> std::string UnencryptedProperties::Get(const char* name, - std::string default_value) const; - -template<> bool UnencryptedProperties::Set(const char* name, - std::string const& value); |