Merge changes from topic 'early-mount-verity' am: 93072f2ce3
am: 2eb715d866
Change-Id: I32cc1ceaaaf1eaad47f7e4c129a520c5835ecd10
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index f9e028b..76b156d 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -108,11 +108,10 @@
return;
}
- std::string fstab_filename = "/fstab." + android::base::GetProperty("ro.hardware", "");
-
- fstab = fs_mgr_read_fstab(fstab_filename.c_str());
+ // read all fstab entries at once from all sources
+ fstab = fs_mgr_read_fstab_default();
if (!fstab) {
- WriteFdFmt(fd, "Failed to open %s\nMaybe run adb root?\n", fstab_filename.c_str());
+ WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
return;
}
diff --git a/fs_mgr/fs_mgr_boot_config.cpp b/fs_mgr/fs_mgr_boot_config.cpp
index ae442cf..9decb27 100644
--- a/fs_mgr/fs_mgr_boot_config.cpp
+++ b/fs_mgr/fs_mgr_boot_config.cpp
@@ -49,8 +49,7 @@
}
// lastly, check the device tree
- static const std::string android_dt_dir("/proc/device-tree/firmware/android");
- std::string file_name = android_dt_dir + "/compatible";
+ std::string file_name = kAndroidDtDir + "/compatible";
std::string dt_value;
if (android::base::ReadFileToString(file_name, &dt_value)) {
if (dt_value != "android,firmware") {
@@ -58,7 +57,7 @@
return false;
}
- file_name = android_dt_dir + "/" + key;
+ file_name = kAndroidDtDir + "/" + key;
// DT entries terminate with '\0' but so do the properties
if (android::base::ReadFileToString(file_name, out_val)) {
return true;
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 10e70d6..f989787 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -15,6 +15,7 @@
*/
#include <ctype.h>
+#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -22,6 +23,10 @@
#include <sys/mount.h>
#include <unistd.h>
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/strings.h>
+
#include "fs_mgr_priv.h"
struct fs_mgr_flag_values {
@@ -290,6 +295,110 @@
return f;
}
+static bool is_dt_compatible() {
+ std::string file_name = kAndroidDtDir + "/compatible";
+ std::string dt_value;
+ if (android::base::ReadFileToString(file_name, &dt_value)) {
+ // trim the trailing '\0' out, otherwise the comparison
+ // will produce false-negatives.
+ dt_value.resize(dt_value.size() - 1);
+ if (dt_value == "android,firmware") {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool is_dt_fstab_compatible() {
+ std::string dt_value;
+ std::string file_name = kAndroidDtDir + "/fstab/compatible";
+
+ if (android::base::ReadFileToString(file_name, &dt_value)) {
+ // trim the trailing '\0' out, otherwise the comparison
+ // will produce false-negatives.
+ dt_value.resize(dt_value.size() - 1);
+ if (dt_value == "android,fstab") {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static std::string read_fstab_from_dt() {
+ std::string fstab;
+ if (!is_dt_compatible() || !is_dt_fstab_compatible()) {
+ return fstab;
+ }
+
+ std::string fstabdir_name = kAndroidDtDir + "/fstab";
+ std::unique_ptr<DIR, int (*)(DIR*)> fstabdir(opendir(fstabdir_name.c_str()), closedir);
+ if (!fstabdir) return fstab;
+
+ dirent* dp;
+ while ((dp = readdir(fstabdir.get())) != NULL) {
+ // skip over name and compatible
+ if (dp->d_type != DT_DIR) {
+ continue;
+ }
+
+ // skip if its not 'vendor', 'odm' or 'system'
+ if (strcmp(dp->d_name, "odm") && strcmp(dp->d_name, "system") &&
+ strcmp(dp->d_name, "vendor")) {
+ continue;
+ }
+
+ // create <dev> <mnt_point> <type> <mnt_flags> <fsmgr_flags>\n
+ std::vector<std::string> fstab_entry;
+ std::string file_name;
+ std::string value;
+ file_name = android::base::StringPrintf("%s/%s/dev", fstabdir_name.c_str(), dp->d_name);
+ if (!android::base::ReadFileToString(file_name, &value)) {
+ LERROR << "dt_fstab: Failed to find device for partition " << dp->d_name;
+ fstab.clear();
+ break;
+ }
+ // trim the terminating '\0' out
+ value.resize(value.size() - 1);
+ fstab_entry.push_back(value);
+ fstab_entry.push_back(android::base::StringPrintf("/%s", dp->d_name));
+
+ file_name = android::base::StringPrintf("%s/%s/type", fstabdir_name.c_str(), dp->d_name);
+ if (!android::base::ReadFileToString(file_name, &value)) {
+ LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
+ fstab.clear();
+ break;
+ }
+ value.resize(value.size() - 1);
+ fstab_entry.push_back(value);
+
+ file_name = android::base::StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name);
+ if (!android::base::ReadFileToString(file_name, &value)) {
+ LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
+ fstab.clear();
+ break;
+ }
+ value.resize(value.size() - 1);
+ fstab_entry.push_back(value);
+
+ file_name = android::base::StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name);
+ if (!android::base::ReadFileToString(file_name, &value)) {
+ LERROR << "dt_fstab: Failed to find type for partition " << dp->d_name;
+ fstab.clear();
+ break;
+ }
+ value.resize(value.size() - 1);
+ fstab_entry.push_back(value);
+
+ fstab += android::base::Join(fstab_entry, " ");
+ fstab += '\n';
+ }
+
+ return fstab;
+}
+
+
struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file)
{
int cnt, entries;
@@ -444,6 +553,84 @@
return fstab;
}
+/* Returns fstab entries parsed from the device tree if they
+ * exist
+ */
+struct fstab *fs_mgr_read_fstab_dt()
+{
+ std::string fstab_buf = read_fstab_from_dt();
+ if (fstab_buf.empty()) {
+ return NULL;
+ }
+
+ std::unique_ptr<FILE, decltype(&fclose)> fstab_file(
+ fmemopen(static_cast<void*>(const_cast<char*>(fstab_buf.c_str())),
+ fstab_buf.length(), "r"), fclose);
+ if (!fstab_file) {
+ return NULL;
+ }
+
+ struct fstab *fstab = fs_mgr_read_fstab_file(fstab_file.get());
+ if (!fstab) {
+ LERROR << "failed to load fstab from kernel:" << std::endl << fstab_buf;
+ }
+
+ return fstab;
+}
+
+/* combines fstab entries passed in from device tree with
+ * the ones found in /fstab.<hardware>
+ */
+struct fstab *fs_mgr_read_fstab_default()
+{
+ struct fstab *fstab = fs_mgr_read_fstab_dt();
+ std::string hw;
+ if (!fs_mgr_get_boot_config("hardware", &hw)) {
+ // if we fail to find this, return whatever was found in device tree
+ LWARNING << "failed to find device hardware name";
+ return fstab;
+ }
+
+ std::string default_fstab = FSTAB_PREFIX + hw;
+ struct fstab *f = fs_mgr_read_fstab(default_fstab.c_str());
+ if (!f) {
+ // return what we have
+ LWARNING << "failed to read fstab entries from '" << default_fstab << "'";
+ return fstab;
+ }
+
+ // return the fstab read from file if device tree doesn't
+ // have one, other wise merge the two
+ if (!fstab) {
+ fstab = f;
+ } else {
+ int total_entries = fstab->num_entries + f->num_entries;
+ fstab->recs = static_cast<struct fstab_rec *>(realloc(
+ fstab->recs, total_entries * (sizeof(struct fstab_rec))));
+ if (!fstab->recs) {
+ LERROR << "failed to allocate fstab recs";
+ fstab->num_entries = 0;
+ fs_mgr_free_fstab(fstab);
+ return NULL;
+ }
+
+ for (int i = fstab->num_entries, j = 0; i < total_entries; i++, j++) {
+ // copy everything and *not* strdup
+ fstab->recs[i] = f->recs[j];
+ }
+
+ // free up fstab entries read from file, but don't cleanup
+ // the strings within f->recs[X] to make sure they are accessible
+ // through fstab->recs[X].
+ free(f->fstab_filename);
+ free(f);
+
+ fstab->num_entries = total_entries;
+ }
+
+ return fstab;
+}
+
void fs_mgr_free_fstab(struct fstab *fstab)
{
int i;
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 478c145..95295d8 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -41,6 +41,8 @@
#define PWARNING PLOG(WARNING) << FS_MGR_TAG
#define PERROR PLOG(ERROR) << FS_MGR_TAG
+const std::string FSTAB_PREFIX("/fstab.");
+
__BEGIN_DECLS
#define CRYPTO_TMPFS_OPTIONS "size=256m,mode=0771,uid=1000,gid=1000"
diff --git a/fs_mgr/fs_mgr_priv_boot_config.h b/fs_mgr/fs_mgr_priv_boot_config.h
index 74bb5eb..8773d33 100644
--- a/fs_mgr/fs_mgr_priv_boot_config.h
+++ b/fs_mgr/fs_mgr_priv_boot_config.h
@@ -20,6 +20,8 @@
#include <sys/cdefs.h>
#include <string>
+const std::string kAndroidDtDir("/proc/device-tree/firmware/android");
+
bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val);
#endif /* __CORE_FS_MGR_PRIV_BOOTCONFIG_H */
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 2c9b0a9..5b81a54 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -46,8 +46,6 @@
#include "fs_mgr_priv.h"
#include "fs_mgr_priv_dm_ioctl.h"
-#define FSTAB_PREFIX "/fstab."
-
#define VERITY_TABLE_RSA_KEY "/verity_key"
#define VERITY_TABLE_HASH_IDX 8
#define VERITY_TABLE_SALT_IDX 9
@@ -694,8 +692,6 @@
int fs_mgr_load_verity_state(int *mode)
{
- char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
- char propbuf[PROPERTY_VALUE_MAX];
int rc = -1;
int i;
int current;
@@ -705,13 +701,9 @@
* logging mode, in which case return that */
*mode = VERITY_MODE_DEFAULT;
- property_get("ro.hardware", propbuf, "");
- snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
-
- fstab = fs_mgr_read_fstab(fstab_filename);
-
+ fstab = fs_mgr_read_fstab_default();
if (!fstab) {
- LERROR << "Failed to read " << fstab_filename;
+ LERROR << "Failed to read default fstab";
goto out;
}
@@ -745,7 +737,6 @@
{
alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
bool system_root = false;
- char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
std::string mount_point;
char propbuf[PROPERTY_VALUE_MAX];
const char *status;
@@ -765,22 +756,16 @@
}
fd = TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC));
-
if (fd == -1) {
PERROR << "Error opening device mapper";
goto out;
}
- property_get("ro.hardware", propbuf, "");
- snprintf(fstab_filename, sizeof(fstab_filename), FSTAB_PREFIX"%s", propbuf);
-
property_get("ro.build.system_root_image", propbuf, "");
system_root = !strcmp(propbuf, "true");
-
- fstab = fs_mgr_read_fstab(fstab_filename);
-
+ fstab = fs_mgr_read_fstab_default();
if (!fstab) {
- LERROR << "Failed to read " << fstab_filename;
+ LERROR << "Failed to read default fstab";
goto out;
}
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 0402b55..52f27ab 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -85,6 +85,8 @@
typedef void (*fs_mgr_verity_state_callback)(struct fstab_rec *fstab,
const char *mount_point, int mode, int status);
+struct fstab *fs_mgr_read_fstab_default();
+struct fstab *fs_mgr_read_fstab_dt();
struct fstab *fs_mgr_read_fstab_file(FILE *fstab_file);
struct fstab *fs_mgr_read_fstab(const char *fstab_path);
void fs_mgr_free_fstab(struct fstab *fstab);
diff --git a/init/init.cpp b/init/init.cpp
index 05f2cfd..3cb1276 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -502,26 +502,30 @@
std::string dt_value;
std::string file_name = StringPrintf("%s/compatible", android_dt_dir);
- android::base::ReadFileToString(file_name, &dt_value);
- if (!dt_value.compare("android,firmware")) {
- LOG(ERROR) << "firmware/android is not compatible with 'android,firmware'";
- return false;
+ if (android::base::ReadFileToString(file_name, &dt_value)) {
+ // trim the trailing '\0' out, otherwise the comparison
+ // will produce false-negatives.
+ dt_value.resize(dt_value.size() - 1);
+ if (dt_value == "android,firmware") {
+ return true;
+ }
}
- return true;
+ return false;
}
static bool is_dt_fstab_compatible() {
std::string dt_value;
std::string file_name = StringPrintf("%s/%s/compatible", android_dt_dir, "fstab");
- android::base::ReadFileToString(file_name, &dt_value);
- if (!dt_value.compare("android,fstab")) {
- LOG(ERROR) << "firmware/android/fstab is not compatible with 'android,fstab'";
- return false;
+ if (android::base::ReadFileToString(file_name, &dt_value)) {
+ dt_value.resize(dt_value.size() - 1);
+ if (dt_value == "android,fstab") {
+ return true;
+ }
}
- return true;
+ return false;
}
static void process_kernel_dt() {
@@ -664,78 +668,6 @@
}
}
-static std::string import_dt_fstab() {
- std::string fstab;
- if (!is_dt_compatible() || !is_dt_fstab_compatible()) {
- return fstab;
- }
-
- std::string fstabdir_name = StringPrintf("%s/fstab", android_dt_dir);
- std::unique_ptr<DIR, int (*)(DIR*)> fstabdir(opendir(fstabdir_name.c_str()), closedir);
- if (!fstabdir) return fstab;
-
- dirent* dp;
- while ((dp = readdir(fstabdir.get())) != NULL) {
- // skip over name and compatible
- if (dp->d_type != DT_DIR) {
- continue;
- }
-
- // skip if its not 'vendor', 'odm' or 'system'
- if (strcmp(dp->d_name, "odm") && strcmp(dp->d_name, "system") &&
- strcmp(dp->d_name, "vendor")) {
- continue;
- }
-
- // create <dev> <mnt_point> <type> <mnt_flags> <fsmgr_flags>\n
- std::vector<std::string> fstab_entry;
- std::string file_name;
- std::string value;
- file_name = StringPrintf("%s/%s/dev", fstabdir_name.c_str(), dp->d_name);
- if (!android::base::ReadFileToString(file_name, &value)) {
- LOG(ERROR) << "dt_fstab: Failed to find device for partition " << dp->d_name;
- fstab.clear();
- break;
- }
- // trim the terminating '\0' out
- value.resize(value.size() - 1);
- fstab_entry.push_back(value);
- fstab_entry.push_back(StringPrintf("/%s", dp->d_name));
-
- file_name = StringPrintf("%s/%s/type", fstabdir_name.c_str(), dp->d_name);
- if (!android::base::ReadFileToString(file_name, &value)) {
- LOG(ERROR) << "dt_fstab: Failed to find type for partition " << dp->d_name;
- fstab.clear();
- break;
- }
- value.resize(value.size() - 1);
- fstab_entry.push_back(value);
-
- file_name = StringPrintf("%s/%s/mnt_flags", fstabdir_name.c_str(), dp->d_name);
- if (!android::base::ReadFileToString(file_name, &value)) {
- LOG(ERROR) << "dt_fstab: Failed to find type for partition " << dp->d_name;
- fstab.clear();
- break;
- }
- value.resize(value.size() - 1);
- fstab_entry.push_back(value);
-
- file_name = StringPrintf("%s/%s/fsmgr_flags", fstabdir_name.c_str(), dp->d_name);
- if (!android::base::ReadFileToString(file_name, &value)) {
- LOG(ERROR) << "dt_fstab: Failed to find type for partition " << dp->d_name;
- fstab.clear();
- break;
- }
- value.resize(value.size() - 1);
- fstab_entry.push_back(value);
-
- fstab += android::base::Join(fstab_entry, " ");
- fstab += '\n';
- }
-
- return fstab;
-}
-
static bool early_mount_one(struct fstab_rec* rec) {
if (rec && fs_mgr_is_verified(rec)) {
// setup verity and create the dm-XX block device
@@ -770,23 +702,16 @@
/* Early mount vendor and ODM partitions. The fstab is read from device-tree. */
static bool early_mount() {
- std::string fstab = import_dt_fstab();
- if (fstab.empty()) {
- LOG(INFO) << "Early mount skipped (missing fstab in device tree)";
+ // first check if device tree fstab entries are compatible
+ if (!is_dt_fstab_compatible()) {
+ LOG(INFO) << "Early mount skipped (missing/incompatible fstab in device tree)";
return true;
}
- std::unique_ptr<FILE, decltype(&fclose)> fstab_file(
- fmemopen(static_cast<void*>(const_cast<char*>(fstab.c_str())), fstab.length(), "r"), fclose);
- if (!fstab_file) {
- PLOG(ERROR) << "Early mount failed to open fstab file in memory";
- return false;
- }
-
- std::unique_ptr<struct fstab, decltype(&fs_mgr_free_fstab)> tab(
- fs_mgr_read_fstab_file(fstab_file.get()), fs_mgr_free_fstab);
+ std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> tab(
+ fs_mgr_read_fstab_dt(), fs_mgr_free_fstab);
if (!tab) {
- LOG(ERROR) << "Early mount fsmgr failed to load fstab from kernel:" << std::endl << fstab;
+ LOG(ERROR) << "Early mount failed to read fstab from device tree";
return false;
}