Revert "Add ParseFstabFromString(), remove ReadFstabFromFp()"

Revert submission 1890098

Reason for revert: Breaks tests, b/206740783
Reverted Changes:
I71190c735:Add ParseFstabFromString(), remove ReadFstabFromFp...
Ic1dd0eb97:Replace strtok_r() with C++-style android::base::T...

Change-Id: I1ded0217670a9bf3f2485120ee0dddf3e854a6fb
This commit is contained in:
Martin Stjernholm 2021-11-17 15:51:01 +00:00
parent c811d139aa
commit 62291bfd5c
3 changed files with 51 additions and 26 deletions

View file

@ -525,23 +525,34 @@ bool EraseFstabEntry(Fstab* fstab, const std::string& mount_point) {
} // namespace
bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab* fstab_out) {
bool ReadFstabFromFp(FILE* fstab_file, bool proc_mounts, Fstab* fstab_out) {
const int expected_fields = proc_mounts ? 4 : 5;
ssize_t len;
size_t alloc_len = 0;
char *line = NULL;
char* p;
Fstab fstab;
for (const auto& line : android::base::Split(fstab_str, "\n")) {
auto fields = android::base::Tokenize(line, " \t");
// Ignore empty lines and comments.
if (fields.empty() || android::base::StartsWith(fields.front(), '#')) {
continue;
while ((len = getline(&line, &alloc_len, fstab_file)) != -1) {
/* if the last character is a newline, shorten the string by 1 byte */
if (line[len - 1] == '\n') {
line[len - 1] = '\0';
}
/* Skip any leading whitespace */
p = line;
while (isspace(*p)) {
p++;
}
/* ignore comments or empty lines */
if (*p == '#' || *p == '\0')
continue;
auto fields = android::base::Tokenize(line, " \t");
if (fields.size() < expected_fields) {
LERROR << "Error parsing fstab: expected " << expected_fields << " fields, got "
<< fields.size();
return false;
goto err;
}
FstabEntry entry;
@ -555,7 +566,7 @@ bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab*
// For /proc/mounts, ignore everything after mnt_freq and mnt_passno
if (!proc_mounts && !ParseFsMgrFlags(std::move(*it++), &entry)) {
LERROR << "Error parsing fs_mgr_flags";
return false;
goto err;
}
if (entry.fs_mgr_flags.logical) {
@ -567,17 +578,21 @@ bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab*
if (fstab.empty()) {
LERROR << "No entries found in fstab";
return false;
goto err;
}
/* If an A/B partition, modify block device to be the real block device */
if (!fs_mgr_update_for_slotselect(&fstab)) {
LERROR << "Error updating for slotselect";
return false;
goto err;
}
free(line);
*fstab_out = std::move(fstab);
return true;
err:
free(line);
return false;
}
void TransformFstabForDsu(Fstab* fstab, const std::string& dsu_slot,
@ -676,18 +691,16 @@ void EnableMandatoryFlags(Fstab* fstab) {
}
bool ReadFstabFromFile(const std::string& path, Fstab* fstab_out) {
const bool is_proc_mounts = (path == "/proc/mounts");
// /proc/mounts could be a symlink to /proc/self/mounts.
const bool follow_symlinks = is_proc_mounts;
std::string fstab_str;
if (!android::base::ReadFileToString(path, &fstab_str, follow_symlinks)) {
PERROR << __FUNCTION__ << "(): failed to read file: '" << path << "'";
auto fstab_file = std::unique_ptr<FILE, decltype(&fclose)>{fopen(path.c_str(), "re"), fclose};
if (!fstab_file) {
PERROR << __FUNCTION__ << "(): cannot open file: '" << path << "'";
return false;
}
bool is_proc_mounts = path == "/proc/mounts";
Fstab fstab;
if (!ParseFstabFromString(fstab_str, is_proc_mounts, &fstab)) {
if (!ReadFstabFromFp(fstab_file.get(), is_proc_mounts, &fstab)) {
LERROR << __FUNCTION__ << "(): failed to load fstab from : '" << path << "'";
return false;
}
@ -734,7 +747,15 @@ bool ReadFstabFromDt(Fstab* fstab, bool verbose) {
return false;
}
if (!ParseFstabFromString(fstab_buf, /* proc_mounts = */ false, fstab)) {
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) {
if (verbose) PERROR << __FUNCTION__ << "(): failed to create a file stream for fstab dt";
return false;
}
if (!ReadFstabFromFp(fstab_file.get(), false, fstab)) {
if (verbose) {
LERROR << __FUNCTION__ << "(): failed to load fstab from kernel:" << std::endl
<< fstab_buf;

View file

@ -19,8 +19,12 @@
#include <fstab/fstab.h>
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
std::string make_fstab_str(reinterpret_cast<const char*>(data), size);
std::unique_ptr<FILE, decltype(&fclose)> fstab_file(
fmemopen(static_cast<void*>(const_cast<uint8_t*>(data)), size, "r"), fclose);
if (fstab_file == nullptr) {
return 0;
}
android::fs_mgr::Fstab fstab;
android::fs_mgr::ParseFstabFromString(make_fstab_str, /* proc_mounts = */ false, &fstab);
android::fs_mgr::ReadFstabFromFp(fstab_file.get(), /* proc_mounts= */ false, &fstab);
return 0;
}

View file

@ -94,8 +94,8 @@ struct FstabEntry {
// Unless explicitly requested, a lookup on mount point should always return the 1st one.
using Fstab = std::vector<FstabEntry>;
// Exported for testability. Regular users should use ReadFstabFromFile().
bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab* fstab_out);
// Exported for testability. Regular users should use ReadFstabFromfile().
bool ReadFstabFromFp(FILE* fstab_file, bool proc_mounts, Fstab* fstab_out);
bool ReadFstabFromFile(const std::string& path, Fstab* fstab);
bool ReadFstabFromDt(Fstab* fstab, bool verbose = true);