summaryrefslogtreecommitdiff
path: root/ext4_utils
diff options
context:
space:
mode:
Diffstat (limited to 'ext4_utils')
-rw-r--r--ext4_utils/Android.mk9
-rw-r--r--ext4_utils/allocate.c2
-rw-r--r--ext4_utils/ext4_crypt.cpp152
-rw-r--r--ext4_utils/ext4_crypt.h30
-rw-r--r--ext4_utils/ext4_crypt_init_extensions.cpp185
-rw-r--r--ext4_utils/ext4_crypt_init_extensions.h21
-rw-r--r--ext4_utils/make_ext4fs.c25
-rw-r--r--ext4_utils/make_ext4fs.h6
-rw-r--r--ext4_utils/unencrypted_properties.cpp99
-rw-r--r--ext4_utils/unencrypted_properties.h74
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);