summaryrefslogtreecommitdiffstats
path: root/roots.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'roots.cpp')
-rw-r--r--roots.cpp38
1 files changed, 32 insertions, 6 deletions
diff --git a/roots.cpp b/roots.cpp
index fdcbfe844..7d7d1bdc7 100644
--- a/roots.cpp
+++ b/roots.cpp
@@ -18,6 +18,7 @@
#include <ctype.h>
#include <fcntl.h>
+#include <stdint.h>
#include <stdlib.h>
#include <sys/mount.h>
#include <sys/stat.h>
@@ -68,8 +69,27 @@ void load_volume_table() {
printf("\n");
}
+// Finds the volume specified by the given path. fs_mgr_get_entry_for_mount_point() does exact match
+// only, so it attempts the prefixes recursively (e.g. "/cache/recovery/last_log",
+// "/cache/recovery", "/cache", "/" for a given path of "/cache/recovery/last_log") and returns the
+// first match or nullptr.
Volume* volume_for_path(const char* path) {
- return fs_mgr_get_entry_for_mount_point(fstab, path);
+ if (path == nullptr || path[0] == '\0') return nullptr;
+ std::string str(path);
+ while (true) {
+ Volume* result = fs_mgr_get_entry_for_mount_point(fstab, str.c_str());
+ if (result != nullptr || str == "/") {
+ return result;
+ }
+ size_t slash = str.find_last_of('/');
+ if (slash == std::string::npos) return nullptr;
+ if (slash == 0) {
+ str = "/";
+ } else {
+ str = str.substr(0, slash);
+ }
+ }
+ return nullptr;
}
// Mount the volume specified by path at the given mount_point.
@@ -178,16 +198,22 @@ static int exec_cmd(const std::vector<std::string>& args) {
return WEXITSTATUS(status);
}
-static ssize_t get_file_size(int fd, uint64_t reserve_len) {
+static int64_t get_file_size(int fd, uint64_t reserve_len) {
struct stat buf;
int ret = fstat(fd, &buf);
if (ret) return 0;
- ssize_t computed_size;
+ int64_t computed_size;
if (S_ISREG(buf.st_mode)) {
computed_size = buf.st_size - reserve_len;
} else if (S_ISBLK(buf.st_mode)) {
- computed_size = get_block_device_size(fd) - reserve_len;
+ uint64_t block_device_size = get_block_device_size(fd);
+ if (block_device_size < reserve_len ||
+ block_device_size > std::numeric_limits<int64_t>::max()) {
+ computed_size = 0;
+ } else {
+ computed_size = block_device_size - reserve_len;
+ }
} else {
computed_size = 0;
}
@@ -231,13 +257,13 @@ int format_volume(const char* volume, const char* directory) {
close(fd);
}
- ssize_t length = 0;
+ int64_t length = 0;
if (v->length != 0) {
length = v->length;
} else if (v->key_loc != nullptr && strcmp(v->key_loc, "footer") == 0) {
android::base::unique_fd fd(open(v->blk_device, O_RDONLY));
if (fd == -1) {
- PLOG(ERROR) << "get_file_size: failed to open " << v->blk_device;
+ PLOG(ERROR) << "format_volume: failed to open " << v->blk_device;
return -1;
}
length = get_file_size(fd.get(), CRYPT_FOOTER_OFFSET);