Merge "Fuzzer for libdm's dm-linear devices creation"
This commit is contained in:
commit
d4a1cd2cdd
2 changed files with 155 additions and 0 deletions
|
|
@ -79,3 +79,19 @@ cc_test {
|
||||||
require_root: true,
|
require_root: true,
|
||||||
test_min_api_level: 29,
|
test_min_api_level: 29,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cc_fuzz {
|
||||||
|
name: "dm_table_fuzzer",
|
||||||
|
defaults: ["fs_mgr_defaults"],
|
||||||
|
srcs: [
|
||||||
|
"dm_linear_fuzzer.cpp",
|
||||||
|
"test_util.cpp",
|
||||||
|
],
|
||||||
|
static_libs: [
|
||||||
|
"libdm",
|
||||||
|
"libbase",
|
||||||
|
"libext2_uuid",
|
||||||
|
"libfs_mgr",
|
||||||
|
"liblog",
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
|
||||||
139
fs_mgr/libdm/dm_linear_fuzzer.cpp
Normal file
139
fs_mgr/libdm/dm_linear_fuzzer.cpp
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
#include <android-base/file.h>
|
||||||
|
#include <android-base/unique_fd.h>
|
||||||
|
#include <libdm/dm_table.h>
|
||||||
|
#include <libdm/loop_control.h>
|
||||||
|
|
||||||
|
#include "test_util.h"
|
||||||
|
|
||||||
|
using namespace android;
|
||||||
|
using namespace android::base;
|
||||||
|
using namespace android::dm;
|
||||||
|
using namespace std;
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This test aims at making the library crash, so these functions are not
|
||||||
|
* really useful.
|
||||||
|
* Keeping them here for future use.
|
||||||
|
*/
|
||||||
|
template <class T, class C>
|
||||||
|
void ASSERT_EQ(const T& /*a*/, const C& /*b*/) {
|
||||||
|
// if (a != b) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void ASSERT_FALSE(const T& /*a*/) {
|
||||||
|
// if (a) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class C>
|
||||||
|
void ASSERT_GE(const T& /*a*/, const C& /*b*/) {
|
||||||
|
// if (a < b) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class C>
|
||||||
|
void ASSERT_NE(const T& /*a*/, const C& /*b*/) {
|
||||||
|
// if (a == b) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void ASSERT_TRUE(const T& /*a*/) {
|
||||||
|
// if (!a) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class C>
|
||||||
|
void EXPECT_EQ(const T& a, const C& b) {
|
||||||
|
ASSERT_EQ(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void EXPECT_TRUE(const T& a) {
|
||||||
|
ASSERT_TRUE(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
|
uint64_t val[6];
|
||||||
|
|
||||||
|
if (size != sizeof(*val)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(&val, &data[0], sizeof(*val));
|
||||||
|
|
||||||
|
unique_fd tmp1(CreateTempFile("file_1", 4096));
|
||||||
|
ASSERT_GE(tmp1, 0);
|
||||||
|
unique_fd tmp2(CreateTempFile("file_2", 4096));
|
||||||
|
ASSERT_GE(tmp2, 0);
|
||||||
|
|
||||||
|
LoopDevice loop_a(tmp1, 10s);
|
||||||
|
ASSERT_TRUE(loop_a.valid());
|
||||||
|
LoopDevice loop_b(tmp2, 10s);
|
||||||
|
ASSERT_TRUE(loop_b.valid());
|
||||||
|
|
||||||
|
// Define a 2-sector device, with each sector mapping to the first sector
|
||||||
|
// of one of our loop devices.
|
||||||
|
DmTable table;
|
||||||
|
ASSERT_TRUE(table.Emplace<DmTargetLinear>(val[0], val[1], loop_a.device(), val[2]));
|
||||||
|
ASSERT_TRUE(table.Emplace<DmTargetLinear>(val[3], val[4], loop_b.device(), val[5]));
|
||||||
|
ASSERT_TRUE(table.valid());
|
||||||
|
ASSERT_EQ(2u, table.num_sectors());
|
||||||
|
|
||||||
|
TempDevice dev("libdm-test-dm-linear", table);
|
||||||
|
ASSERT_TRUE(dev.valid());
|
||||||
|
ASSERT_FALSE(dev.path().empty());
|
||||||
|
|
||||||
|
auto& dm = DeviceMapper::Instance();
|
||||||
|
|
||||||
|
dev_t dev_number;
|
||||||
|
ASSERT_TRUE(dm.GetDeviceNumber(dev.name(), &dev_number));
|
||||||
|
ASSERT_NE(dev_number, 0);
|
||||||
|
|
||||||
|
std::string dev_string;
|
||||||
|
ASSERT_TRUE(dm.GetDeviceString(dev.name(), &dev_string));
|
||||||
|
ASSERT_FALSE(dev_string.empty());
|
||||||
|
|
||||||
|
// Test GetTableStatus.
|
||||||
|
vector<DeviceMapper::TargetInfo> targets;
|
||||||
|
ASSERT_TRUE(dm.GetTableStatus(dev.name(), &targets));
|
||||||
|
ASSERT_EQ(targets.size(), 2);
|
||||||
|
EXPECT_EQ(strcmp(targets[0].spec.target_type, "linear"), 0);
|
||||||
|
EXPECT_TRUE(targets[0].data.empty());
|
||||||
|
EXPECT_EQ(targets[0].spec.sector_start, 0);
|
||||||
|
EXPECT_EQ(targets[0].spec.length, 1);
|
||||||
|
EXPECT_EQ(strcmp(targets[1].spec.target_type, "linear"), 0);
|
||||||
|
EXPECT_TRUE(targets[1].data.empty());
|
||||||
|
EXPECT_EQ(targets[1].spec.sector_start, 1);
|
||||||
|
EXPECT_EQ(targets[1].spec.length, 1);
|
||||||
|
|
||||||
|
// Test GetTargetType().
|
||||||
|
EXPECT_EQ(DeviceMapper::GetTargetType(targets[0].spec), std::string{"linear"});
|
||||||
|
EXPECT_EQ(DeviceMapper::GetTargetType(targets[1].spec), std::string{"linear"});
|
||||||
|
|
||||||
|
// Normally the TestDevice destructor would delete this, but at least one
|
||||||
|
// test should ensure that device deletion works.
|
||||||
|
ASSERT_TRUE(dev.Destroy());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue