Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b0a9c30b authored by David Anderson's avatar David Anderson
Browse files

libfiemap: Fix removal of corrupted split fiemaps.

If a split fiemap header gets corrupted, we could get ENAMETOOLONG and
removal fails. Handle this gracefully.

Bug: N/A
Test: fiemap_writer_test
Change-Id: I4af9ca7ad4b4fa87a91ff05b8fadac4258006ab6
parent edefadd2
Loading
Loading
Loading
Loading
+22 −0
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


#include <fcntl.h>
#include <fcntl.h>
#include <inttypes.h>
#include <inttypes.h>
#include <linux/limits.h>
#include <stdint.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
@@ -299,6 +300,27 @@ TEST_F(SplitFiemapTest, DeleteOnFail) {
    ASSERT_EQ(errno, ENOENT);
    ASSERT_EQ(errno, ENOENT);
}
}


TEST_F(SplitFiemapTest, CorruptSplit) {
    unique_fd fd(open(testfile.c_str(), O_RDWR | O_CREAT | O_TRUNC, 0700));
    ASSERT_GE(fd, 0);

    // Make a giant random string.
    std::vector<char> data;
    for (size_t i = 0x1; i < 0x7f; i++) {
        for (size_t j = 0; j < 100; j++) {
            data.emplace_back(i);
        }
    }
    ASSERT_GT(data.size(), PATH_MAX);

    data.emplace_back('\n');

    ASSERT_TRUE(android::base::WriteFully(fd, data.data(), data.size()));
    fd = {};

    ASSERT_TRUE(SplitFiemap::RemoveSplitFiles(testfile));
}

static string ReadSplitFiles(const std::string& base_path, size_t num_files) {
static string ReadSplitFiles(const std::string& base_path, size_t num_files) {
    std::string result;
    std::string result;
    for (int i = 0; i < num_files; i++) {
    for (int i = 0; i < num_files; i++) {
+3 −0
Original line number Original line Diff line number Diff line
@@ -193,6 +193,9 @@ bool SplitFiemap::RemoveSplitFiles(const std::string& file_path, std::string* me
    std::vector<std::string> files;
    std::vector<std::string> files;
    if (GetSplitFileList(file_path, &files)) {
    if (GetSplitFileList(file_path, &files)) {
        for (const auto& file : files) {
        for (const auto& file : files) {
            if (access(file.c_str(), F_OK) != 0 && (errno == ENOENT || errno == ENAMETOOLONG)) {
                continue;
            }
            ok &= android::base::RemoveFileIfExists(file, message);
            ok &= android::base::RemoveFileIfExists(file, message);
        }
        }
    }
    }