diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp index c1aafdac9..6f24fe1dc 100644 --- a/fs_mgr/fs_mgr.cpp +++ b/fs_mgr/fs_mgr.cpp @@ -1610,38 +1610,6 @@ bool fs_mgr_swapon_all(const Fstab& fstab) { return ret; } -bool fs_mgr_load_verity_state(int* mode) { - /* return the default mode, unless any of the verified partitions are in - * logging mode, in which case return that */ - *mode = VERITY_MODE_DEFAULT; - - Fstab fstab; - if (!ReadDefaultFstab(&fstab)) { - LERROR << "Failed to read default fstab"; - return false; - } - - for (const auto& entry : fstab) { - if (entry.fs_mgr_flags.avb) { - *mode = VERITY_MODE_RESTART; // avb only supports restart mode. - break; - } else if (!entry.fs_mgr_flags.verify) { - continue; - } - - int current; - if (load_verity_state(entry, ¤t) < 0) { - continue; - } - if (current != VERITY_MODE_DEFAULT) { - *mode = current; - break; - } - } - - return true; -} - bool fs_mgr_is_verity_enabled(const FstabEntry& entry) { if (!entry.fs_mgr_flags.verify && !entry.fs_mgr_flags.avb) { return false; diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp index da049efa5..78455d4a4 100644 --- a/fs_mgr/fs_mgr_fstab.cpp +++ b/fs_mgr/fs_mgr_fstab.cpp @@ -261,10 +261,6 @@ void ParseFsMgrFlags(const std::string& flags, FstabEntry* entry) { LWARNING << "Warning: zramsize= flag malformed: " << arg; } } - } else if (StartsWith(flag, "verify=")) { - // If the verify flag is followed by an = and the location for the verity state. - entry->fs_mgr_flags.verify = true; - entry->verity_loc = arg; } else if (StartsWith(flag, "forceencrypt=")) { // The forceencrypt flag is followed by an = and the location of the keys. entry->fs_mgr_flags.force_crypt = true; diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h index 70abf5b78..c36fd3dde 100644 --- a/fs_mgr/fs_mgr_priv.h +++ b/fs_mgr/fs_mgr_priv.h @@ -99,7 +99,6 @@ bool fs_mgr_update_for_slotselect(android::fs_mgr::Fstab* fstab); bool fs_mgr_is_device_unlocked(); const std::string& get_android_dt_dir(); bool is_dt_compatible(); -int load_verity_state(const android::fs_mgr::FstabEntry& entry, int* mode); bool fs_mgr_is_ext4(const std::string& blk_device); bool fs_mgr_is_f2fs(const std::string& blk_device); diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp index 3f0915780..1deb1ac55 100644 --- a/fs_mgr/fs_mgr_verity.cpp +++ b/fs_mgr/fs_mgr_verity.cpp @@ -275,248 +275,6 @@ static int load_verity_table(android::dm::DeviceMapper& dm, const std::string& n return 0; } -static int check_verity_restart(const char *fname) -{ - char buffer[VERITY_KMSG_BUFSIZE + 1]; - int fd; - int rc = 0; - ssize_t size; - struct stat s; - - fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC)); - - if (fd == -1) { - if (errno != ENOENT) { - PERROR << "Failed to open " << fname; - } - goto out; - } - - if (fstat(fd, &s) == -1) { - PERROR << "Failed to fstat " << fname; - goto out; - } - - size = VERITY_KMSG_BUFSIZE; - - if (size > s.st_size) { - size = s.st_size; - } - - if (lseek(fd, s.st_size - size, SEEK_SET) == -1) { - PERROR << "Failed to lseek " << (intmax_t)(s.st_size - size) << " " << fname; - goto out; - } - - if (!android::base::ReadFully(fd, buffer, size)) { - PERROR << "Failed to read " << size << " bytes from " << fname; - goto out; - } - - buffer[size] = '\0'; - - if (strstr(buffer, VERITY_KMSG_RESTART) != NULL) { - rc = 1; - } - -out: - if (fd != -1) { - close(fd); - } - - return rc; -} - -static int was_verity_restart() -{ - static const char* files[] = { - // clang-format off - "/sys/fs/pstore/console-ramoops-0", - "/sys/fs/pstore/console-ramoops", - "/proc/last_kmsg", - NULL - // clang-format on - }; - int i; - - for (i = 0; files[i]; ++i) { - if (check_verity_restart(files[i])) { - return 1; - } - } - - return 0; -} - -static int metadata_add(FILE *fp, long start, const char *tag, - unsigned int length, off64_t *offset) -{ - if (fseek(fp, start, SEEK_SET) < 0 || - fprintf(fp, "%s %u\n", tag, length) < 0) { - return -1; - } - - *offset = ftell(fp); - - if (fseek(fp, length, SEEK_CUR) < 0 || - fprintf(fp, METADATA_EOD " 0\n") < 0) { - return -1; - } - - return 0; -} - -static int metadata_find(const char *fname, const char *stag, - unsigned int slength, off64_t *offset) -{ - char tag[METADATA_TAG_MAX_LENGTH + 1]; - int rc = -1; - int n; - long start = 0x4000; /* skip cryptfs metadata area */ - uint32_t magic; - unsigned int length = 0; - - if (!fname) { - return -1; - } - - auto fp = std::unique_ptr<FILE, decltype(&fclose)>{fopen(fname, "re+"), fclose}; - - if (!fp) { - PERROR << "Failed to open " << fname; - return -1; - } - - /* check magic */ - if (fseek(fp.get(), start, SEEK_SET) < 0 || fread(&magic, sizeof(magic), 1, fp.get()) != 1) { - PERROR << "Failed to read magic from " << fname; - return -1; - } - - if (magic != METADATA_MAGIC) { - magic = METADATA_MAGIC; - - if (fseek(fp.get(), start, SEEK_SET) < 0 || - fwrite(&magic, sizeof(magic), 1, fp.get()) != 1) { - PERROR << "Failed to write magic to " << fname; - return -1; - } - - rc = metadata_add(fp.get(), start + sizeof(magic), stag, slength, offset); - if (rc < 0) { - PERROR << "Failed to add metadata to " << fname; - } - - return rc; - } - - start += sizeof(magic); - - while (1) { - n = fscanf(fp.get(), "%" STRINGIFY(METADATA_TAG_MAX_LENGTH) "s %u\n", tag, &length); - - if (n == 2 && strcmp(tag, METADATA_EOD)) { - /* found a tag */ - start = ftell(fp.get()); - - if (!strcmp(tag, stag) && length == slength) { - *offset = start; - return 0; - } - - start += length; - - if (fseek(fp.get(), length, SEEK_CUR) < 0) { - PERROR << "Failed to seek " << fname; - return -1; - } - } else { - rc = metadata_add(fp.get(), start, stag, slength, offset); - if (rc < 0) { - PERROR << "Failed to write metadata to " << fname; - } - return rc; - } - } -} - -static int write_verity_state(const char *fname, off64_t offset, int32_t mode) -{ - int fd; - int rc = -1; - struct verity_state s = { VERITY_STATE_HEADER, VERITY_STATE_VERSION, mode }; - - fd = TEMP_FAILURE_RETRY(open(fname, O_WRONLY | O_SYNC | O_CLOEXEC)); - - if (fd == -1) { - PERROR << "Failed to open " << fname; - goto out; - } - - if (TEMP_FAILURE_RETRY(pwrite64(fd, &s, sizeof(s), offset)) != sizeof(s)) { - PERROR << "Failed to write " << sizeof(s) << " bytes to " << fname - << " to offset " << offset; - goto out; - } - - rc = 0; - -out: - if (fd != -1) { - close(fd); - } - - return rc; -} - -static int read_verity_state(const char *fname, off64_t offset, int *mode) -{ - int fd = -1; - int rc = -1; - struct verity_state s; - - fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | O_CLOEXEC)); - - if (fd == -1) { - PERROR << "Failed to open " << fname; - goto out; - } - - if (TEMP_FAILURE_RETRY(pread64(fd, &s, sizeof(s), offset)) != sizeof(s)) { - PERROR << "Failed to read " << sizeof(s) << " bytes from " << fname - << " offset " << offset; - goto out; - } - - if (s.header != VERITY_STATE_HEADER) { - /* space allocated, but no state written. write default state */ - *mode = VERITY_MODE_DEFAULT; - rc = write_verity_state(fname, offset, *mode); - goto out; - } - - if (s.version != VERITY_STATE_VERSION) { - LERROR << "Unsupported verity state version (" << s.version << ")"; - goto out; - } - - if (s.mode < VERITY_MODE_EIO || - s.mode > VERITY_MODE_LAST) { - LERROR << "Unsupported verity mode (" << s.mode << ")"; - goto out; - } - - *mode = s.mode; - rc = 0; - -out: - if (fd != -1) { - close(fd); - } - - return rc; -} - static int read_partition(const char *path, uint64_t size) { char buf[READ_BUF_SIZE]; @@ -540,119 +298,23 @@ static int read_partition(const char *path, uint64_t size) return 0; } -static int compare_last_signature(const FstabEntry& entry, int* match) { - char tag[METADATA_TAG_MAX_LENGTH + 1]; - int fd = -1; - int rc = -1; - off64_t offset = 0; - struct fec_handle *f = NULL; - struct fec_verity_metadata verity; - uint8_t curr[SHA256_DIGEST_LENGTH]; - uint8_t prev[SHA256_DIGEST_LENGTH]; - - *match = 1; - - if (fec_open(&f, entry.blk_device.c_str(), O_RDONLY, FEC_VERITY_DISABLE, FEC_DEFAULT_ROOTS) == - -1) { - PERROR << "Failed to open '" << entry.blk_device << "'"; - return rc; - } - - // read verity metadata - if (fec_verity_get_metadata(f, &verity) == -1) { - PERROR << "Failed to get verity metadata '" << entry.blk_device << "'"; - goto out; - } - - SHA256(verity.signature, sizeof(verity.signature), curr); - - if (snprintf(tag, sizeof(tag), VERITY_LASTSIG_TAG "_%s", basename(entry.mount_point.c_str())) >= - (int)sizeof(tag)) { - LERROR << "Metadata tag name too long for " << entry.mount_point; - goto out; - } - - if (metadata_find(entry.verity_loc.c_str(), tag, SHA256_DIGEST_LENGTH, &offset) < 0) { - goto out; - } - - fd = TEMP_FAILURE_RETRY(open(entry.verity_loc.c_str(), O_RDWR | O_SYNC | O_CLOEXEC)); - - if (fd == -1) { - PERROR << "Failed to open " << entry.verity_loc; - goto out; - } - - if (TEMP_FAILURE_RETRY(pread64(fd, prev, sizeof(prev), offset)) != sizeof(prev)) { - PERROR << "Failed to read " << sizeof(prev) << " bytes from " << entry.verity_loc - << " offset " << offset; - goto out; - } - - *match = !memcmp(curr, prev, SHA256_DIGEST_LENGTH); - - if (!*match) { - /* update current signature hash */ - if (TEMP_FAILURE_RETRY(pwrite64(fd, curr, sizeof(curr), - offset)) != sizeof(curr)) { - PERROR << "Failed to write " << sizeof(curr) << " bytes to " << entry.verity_loc - << " offset " << offset; - goto out; - } - } - - rc = 0; - -out: - fec_close(f); - return rc; -} - -static int get_verity_state_offset(const FstabEntry& entry, off64_t* offset) { - char tag[METADATA_TAG_MAX_LENGTH + 1]; - - if (snprintf(tag, sizeof(tag), VERITY_STATE_TAG "_%s", basename(entry.mount_point.c_str())) >= - (int)sizeof(tag)) { - LERROR << "Metadata tag name too long for " << entry.mount_point; - return -1; - } - - return metadata_find(entry.verity_loc.c_str(), tag, sizeof(struct verity_state), offset); -} - -int load_verity_state(const FstabEntry& entry, int* mode) { +bool fs_mgr_load_verity_state(int* mode) { // unless otherwise specified, use EIO mode. *mode = VERITY_MODE_EIO; - // use the kernel parameter if set. - std::string veritymode; - if (fs_mgr_get_boot_config("veritymode", &veritymode)) { - if (veritymode == "enforcing") { - *mode = VERITY_MODE_DEFAULT; - } - return 0; + // The bootloader communicates verity mode via the kernel commandline + std::string verity_mode; + if (!fs_mgr_get_boot_config("veritymode", &verity_mode)) { + return false; } - off64_t offset = 0; - if (get_verity_state_offset(entry, &offset) < 0) { - /* fall back to stateless behavior */ - return 0; - } - - if (was_verity_restart()) { - /* device was restarted after dm-verity detected a corrupted - * block, so use EIO mode */ - return write_verity_state(entry.verity_loc.c_str(), offset, *mode); - } - - int match = 0; - if (!compare_last_signature(entry, &match) && !match) { - /* partition has been reflashed, reset dm-verity state */ + if (verity_mode == "enforcing") { *mode = VERITY_MODE_DEFAULT; - return write_verity_state(entry.verity_loc.c_str(), offset, *mode); + } else if (verity_mode == "logging") { + *mode = VERITY_MODE_LOGGING; } - return read_verity_state(entry.verity_loc.c_str(), offset, mode); + return true; } // Update the verity table using the actual block device path. @@ -759,7 +421,7 @@ int fs_mgr_setup_verity(FstabEntry* entry, bool wait_for_verity_dev) { params.ecc_dev = entry->blk_device.c_str(); - if (load_verity_state(*entry, ¶ms.mode) < 0) { + if (!fs_mgr_load_verity_state(¶ms.mode)) { /* if accessing or updating the state failed, switch to the default * safe mode. This makes sure the device won't end up in an endless * restart loop, and no corrupted data will be exposed to userspace diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h index d7afed654..c7193ab3c 100644 --- a/fs_mgr/include_fstab/fstab/fstab.h +++ b/fs_mgr/include_fstab/fstab/fstab.h @@ -38,7 +38,6 @@ struct FstabEntry { std::string fs_options; std::string key_loc; std::string key_dir; - std::string verity_loc; off64_t length = 0; std::string label; int partnum = -1; diff --git a/fs_mgr/tests/fs_mgr_test.cpp b/fs_mgr/tests/fs_mgr_test.cpp index 72afa699b..6d8759404 100644 --- a/fs_mgr/tests/fs_mgr_test.cpp +++ b/fs_mgr/tests/fs_mgr_test.cpp @@ -394,7 +394,7 @@ TEST(fs_mgr, ReadFstabFromFile_FsMgrOptions_AllBad) { std::string fstab_contents = R"fs( source none0 swap defaults encryptable,forceencrypt,fileencryption,forcefdeorfbe,keydirectory,length,swapprio,zramsize,max_comp_streams,reservedsize,eraseblk,logicalblk,sysfs_path,zram_loopback_path,zram_loopback_size,zram_backing_dev_path -source none1 swap defaults encryptable=,forceencrypt=,fileencryption=,keydirectory=,length=,swapprio=,zramsize=,max_comp_streams=,verify=,avb=,reservedsize=,eraseblk=,logicalblk=,sysfs_path=,zram_loopback_path=,zram_loopback_size=,zram_backing_dev_path= +source none1 swap defaults encryptable=,forceencrypt=,fileencryption=,keydirectory=,length=,swapprio=,zramsize=,max_comp_streams=,avb=,reservedsize=,eraseblk=,logicalblk=,sysfs_path=,zram_loopback_path=,zram_loopback_size=,zram_backing_dev_path= source none2 swap defaults forcefdeorfbe= @@ -413,7 +413,6 @@ source none2 swap defaults forcefdeorfbe= } EXPECT_EQ("", entry->key_loc); EXPECT_EQ("", entry->key_dir); - EXPECT_EQ("", entry->verity_loc); EXPECT_EQ(0, entry->length); EXPECT_EQ("", entry->label); EXPECT_EQ(-1, entry->partnum); @@ -437,13 +436,11 @@ source none2 swap defaults forcefdeorfbe= flags.crypt = true; flags.force_crypt = true; flags.file_encryption = true; - flags.verify = true; flags.avb = true; EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); } EXPECT_EQ("", entry->key_loc); EXPECT_EQ("", entry->key_dir); - EXPECT_EQ("", entry->verity_loc); EXPECT_EQ(0, entry->length); EXPECT_EQ("", entry->label); EXPECT_EQ(-1, entry->partnum); @@ -639,29 +636,6 @@ source none5 swap defaults zramsize=% EXPECT_EQ(0, entry->zram_size); } -TEST(fs_mgr, ReadFstabFromFile_FsMgrOptions_Verify) { - TemporaryFile tf; - ASSERT_TRUE(tf.fd != -1); - std::string fstab_contents = R"fs( -source none0 swap defaults verify=/dir/key -)fs"; - - ASSERT_TRUE(android::base::WriteStringToFile(fstab_contents, tf.path)); - - Fstab fstab; - EXPECT_TRUE(ReadFstabFromFile(tf.path, &fstab)); - ASSERT_EQ(1U, fstab.size()); - - auto entry = fstab.begin(); - EXPECT_EQ("none0", entry->mount_point); - - FstabEntry::FsMgrFlags flags = {}; - flags.verify = true; - EXPECT_TRUE(CompareFlags(flags, entry->fs_mgr_flags)); - - EXPECT_EQ("/dir/key", entry->verity_loc); -} - TEST(fs_mgr, ReadFstabFromFile_FsMgrOptions_ForceEncrypt) { TemporaryFile tf; ASSERT_TRUE(tf.fd != -1); diff --git a/init/README.md b/init/README.md index 28a106a3a..d7f809f8a 100644 --- a/init/README.md +++ b/init/README.md @@ -586,9 +586,6 @@ Commands `umount <path>` > Unmount the filesystem mounted at that path. -`verity_load_state` -> Internal implementation detail used to load dm-verity state. - `verity_update_state <mount-point>` > Internal implementation detail used to update dm-verity state and set the partition._mount-point_.verified properties used by adb remount diff --git a/init/builtins.cpp b/init/builtins.cpp index 06da4be9a..62e0f8fa6 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -707,17 +707,6 @@ static Result<Success> do_sysclktz(const BuiltinArguments& args) { return Success(); } -static Result<Success> do_verity_load_state(const BuiltinArguments& args) { - int mode = -1; - bool loaded = fs_mgr_load_verity_state(&mode); - if (loaded && mode != VERITY_MODE_DEFAULT) { - ActionManager::GetInstance().QueueEventTrigger("verity-logging"); - } - if (!loaded) return Error() << "Could not load verity state"; - - return Success(); -} - static Result<Success> do_verity_update_state(const BuiltinArguments& args) { int mode; if (!fs_mgr_load_verity_state(&mode)) { @@ -1150,7 +1139,6 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { {"symlink", {2, 2, {true, do_symlink}}}, {"sysclktz", {1, 1, {false, do_sysclktz}}}, {"trigger", {1, 1, {false, do_trigger}}}, - {"verity_load_state", {0, 0, {false, do_verity_load_state}}}, {"verity_update_state", {0, 0, {false, do_verity_update_state}}}, {"wait", {1, 2, {true, do_wait}}}, {"wait_for_prop", {2, 2, {false, do_wait_for_prop}}}, diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp index 3e76556ff..85fa87496 100644 --- a/init/first_stage_mount.cpp +++ b/init/first_stage_mount.cpp @@ -644,7 +644,6 @@ void FirstStageMount::UseGsiIfPresent() { } bool FirstStageMountVBootV1::GetDmVerityDevices() { - std::string verity_loc_device; need_dm_verity_ = false; for (const auto& fstab_entry : fstab_) { @@ -657,21 +656,9 @@ bool FirstStageMountVBootV1::GetDmVerityDevices() { if (fstab_entry.fs_mgr_flags.verify) { need_dm_verity_ = true; } - // Checks if verity metadata is on a separate partition. Note that it is - // not partition specific, so there must be only one additional partition - // that carries verity state. - if (!fstab_entry.verity_loc.empty()) { - if (verity_loc_device.empty()) { - verity_loc_device = fstab_entry.verity_loc; - } else if (verity_loc_device != fstab_entry.verity_loc) { - LOG(ERROR) << "More than one verity_loc found: " << verity_loc_device << ", " - << fstab_entry.verity_loc; - return false; - } - } } - // Includes the partition names of fstab records and verity_loc_device (if any). + // Includes the partition names of fstab records. // Notes that fstab_rec->blk_device has A/B suffix updated by fs_mgr when A/B is used. for (const auto& fstab_entry : fstab_) { if (!fstab_entry.fs_mgr_flags.logical) { @@ -679,10 +666,6 @@ bool FirstStageMountVBootV1::GetDmVerityDevices() { } } - if (!verity_loc_device.empty()) { - required_devices_partition_names_.emplace(basename(verity_loc_device.c_str())); - } - return true; }