diff options
author | Paul Crowley <paulcrowley@google.com> | 2019-08-09 14:19:11 -0700 |
---|---|---|
committer | Paul Crowley <paulcrowley@google.com> | 2019-08-25 11:16:46 -0700 |
commit | 4c350ec37ef76d2de0cfbf1d5da95efafd1e4906 (patch) | |
tree | 8cfcbe05de97fdbea844e29a8e02568ef0e4474b /libfscrypt | |
parent | abde21870e073997a766055ad660dfd5a8f1fa22 (diff) | |
download | extras-4c350ec37ef76d2de0cfbf1d5da95efafd1e4906.tar.gz |
If the rollback directories won't encrypt, wipe them
/data/rollback and /data/rollback-observer used to be created
unencrypted by system-server. If they are unencrypted and have
content, force them to be encrypted by wiping their contents.
Bug: b/139193659
Test: Put content in these directories, then reboot and see it wiped.
Cherrypicked-from: 58a49c3ae59d250cc1db49ce5a2678bf19bb92c3
Change-Id: I0320eb645ebe86965928acbacc8ad01dae2d5ba5
Merged-In: I0320eb645ebe86965928acbacc8ad01dae2d5ba5
Diffstat (limited to 'libfscrypt')
-rw-r--r-- | libfscrypt/fscrypt_init_extensions.cpp | 85 |
1 files changed, 72 insertions, 13 deletions
diff --git a/libfscrypt/fscrypt_init_extensions.cpp b/libfscrypt/fscrypt_init_extensions.cpp index f132f8a0..964ead65 100644 --- a/libfscrypt/fscrypt_init_extensions.cpp +++ b/libfscrypt/fscrypt_init_extensions.cpp @@ -14,11 +14,19 @@ * limitations under the License. */ -#include "fscrypt/fscrypt.h" #include "fscrypt/fscrypt_init_extensions.h" +#include <android-base/file.h> +#include <android-base/logging.h> +#include <android-base/stringprintf.h> +#include <android-base/strings.h> +#include <cutils/properties.h> +#include <cutils/sockets.h> #include <dirent.h> #include <errno.h> +#include <fts.h> +#include <keyutils.h> +#include <logwrap/logwrap.h> #include <sys/mount.h> #include <sys/stat.h> #include <unistd.h> @@ -26,14 +34,7 @@ #include <string> #include <vector> -#include <android-base/file.h> -#include <android-base/logging.h> -#include <android-base/stringprintf.h> -#include <android-base/strings.h> -#include <cutils/properties.h> -#include <cutils/sockets.h> -#include <keyutils.h> -#include <logwrap/logwrap.h> +#include "fscrypt/fscrypt.h" #define TAG "fscrypt" @@ -54,9 +55,52 @@ int fscrypt_install_keyring() return 0; } +// TODO(b/139378601): use a single central implementation of this. +static void delete_dir_contents(const char* dir) { + char* const paths[2] = {const_cast<char*>(dir), nullptr}; + FTS* fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, nullptr); + FTSENT* cur; + while ((cur = fts_read(fts)) != nullptr) { + if (cur->fts_info == FTS_ERR) { + PLOG(ERROR) << "fts_read"; + break; + } + if (strcmp(dir, cur->fts_path) == 0) { + continue; + } + switch (cur->fts_info) { + case FTS_D: + break; // Ignore these + case FTS_DP: + if (rmdir(cur->fts_path) == -1) { + PLOG(ERROR) << "rmdir " << cur->fts_path; + } + break; + default: + PLOG(ERROR) << "FTS unexpected type " << cur->fts_info << " at " << cur->fts_path; + if (rmdir(cur->fts_path) != -1) break; + // FALLTHRU (for gcc, lint, pcc, etc; and following for clang) + FALLTHROUGH_INTENDED; + case FTS_F: + case FTS_SL: + case FTS_SLNONE: + if (unlink(cur->fts_path) == -1) { + PLOG(ERROR) << "unlink " << cur->fts_path; + } + break; + } + } + + if (fts_close(fts) != 0) { + PLOG(ERROR) << "fts_close"; + } +} + int fscrypt_set_directory_policy(const char* dir) { - if (!dir || strncmp(dir, "/data/", 6)) { + const std::string prefix = "/data/"; + + if (!dir || strncmp(dir, prefix.c_str(), prefix.size())) { return 0; } @@ -71,7 +115,7 @@ int fscrypt_set_directory_policy(const char* dir) // To make this less restrictive, consider using a policy file. // However this is overkill for as long as the policy is simply // to apply a global policy to all /data folders created via makedir - if (strchr(dir + 6, '/')) { + if (strchr(dir + prefix.size(), '/')) { return 0; } @@ -88,14 +132,29 @@ int fscrypt_set_directory_policy(const char* dir) "apex", "preloads", "app-staging", "gsi", }; - std::string prefix = "/data/"; for (const auto& d: directories_to_exclude) { if ((prefix + d) == dir) { LOG(INFO) << "Not setting policy on " << dir; return 0; } } - return set_system_de_policy_on(dir); + int err = set_system_de_policy_on(dir); + if (err == 0) { + return 0; + } + // Empty these directories if policy setting fails. + std::vector<std::string> wipe_on_failure = { + "rollback", "rollback-observer", // b/139193659 + }; + for (const auto& d : wipe_on_failure) { + if ((prefix + d) == dir) { + LOG(ERROR) << "Setting policy failed, deleting: " << dir; + delete_dir_contents(dir); + err = set_system_de_policy_on(dir); + break; + } + } + return err; } static int set_system_de_policy_on(char const* dir) { |