1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <stddef.h>
18 #include <stdint.h>
19 #include <string.h>
20
21 #include <chrono>
22
23 #include <android-base/file.h>
24 #include <android-base/unique_fd.h>
25 #include <libdm/dm_table.h>
26 #include <libdm/loop_control.h>
27
28 #include "test_util.h"
29
30 using namespace android;
31 using namespace android::base;
32 using namespace android::dm;
33 using namespace std;
34 using namespace std::chrono_literals;
35
36 /*
37 * This test aims at making the library crash, so these functions are not
38 * really useful.
39 * Keeping them here for future use.
40 */
41 template <class T, class C>
ASSERT_EQ(const T &,const C &)42 void ASSERT_EQ(const T& /*a*/, const C& /*b*/) {
43 // if (a != b) {}
44 }
45
46 template <class T>
ASSERT_FALSE(const T &)47 void ASSERT_FALSE(const T& /*a*/) {
48 // if (a) {}
49 }
50
51 template <class T, class C>
ASSERT_GE(const T &,const C &)52 void ASSERT_GE(const T& /*a*/, const C& /*b*/) {
53 // if (a < b) {}
54 }
55
56 template <class T, class C>
ASSERT_NE(const T &,const C &)57 void ASSERT_NE(const T& /*a*/, const C& /*b*/) {
58 // if (a == b) {}
59 }
60
61 template <class T>
ASSERT_TRUE(const T &)62 void ASSERT_TRUE(const T& /*a*/) {
63 // if (!a) {}
64 }
65
66 template <class T, class C>
EXPECT_EQ(const T & a,const C & b)67 void EXPECT_EQ(const T& a, const C& b) {
68 ASSERT_EQ(a, b);
69 }
70
71 template <class T>
EXPECT_TRUE(const T & a)72 void EXPECT_TRUE(const T& a) {
73 ASSERT_TRUE(a);
74 }
75
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)76 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
77 uint64_t val[6];
78
79 if (size != sizeof(val)) {
80 return 0;
81 }
82
83 memcpy(&val, &data[0], sizeof(*val));
84
85 unique_fd tmp1(CreateTempFile("file_1", 4096));
86 ASSERT_GE(tmp1, 0);
87 unique_fd tmp2(CreateTempFile("file_2", 4096));
88 ASSERT_GE(tmp2, 0);
89
90 LoopDevice loop_a(tmp1, 10s);
91 ASSERT_TRUE(loop_a.valid());
92 LoopDevice loop_b(tmp2, 10s);
93 ASSERT_TRUE(loop_b.valid());
94
95 // Define a 2-sector device, with each sector mapping to the first sector
96 // of one of our loop devices.
97 DmTable table;
98 ASSERT_TRUE(table.Emplace<DmTargetLinear>(val[0], val[1], loop_a.device(), val[2]));
99 ASSERT_TRUE(table.Emplace<DmTargetLinear>(val[3], val[4], loop_b.device(), val[5]));
100 ASSERT_TRUE(table.valid());
101 ASSERT_EQ(2u, table.num_sectors());
102
103 TempDevice dev("libdm-test-dm-linear", table);
104 ASSERT_TRUE(dev.valid());
105 ASSERT_FALSE(dev.path().empty());
106
107 auto& dm = DeviceMapper::Instance();
108
109 dev_t dev_number;
110 ASSERT_TRUE(dm.GetDeviceNumber(dev.name(), &dev_number));
111 ASSERT_NE(dev_number, 0);
112
113 std::string dev_string;
114 ASSERT_TRUE(dm.GetDeviceString(dev.name(), &dev_string));
115 ASSERT_FALSE(dev_string.empty());
116
117 // Test GetTableStatus.
118 vector<DeviceMapper::TargetInfo> targets;
119 ASSERT_TRUE(dm.GetTableStatus(dev.name(), &targets));
120 ASSERT_EQ(targets.size(), 2);
121 EXPECT_EQ(strcmp(targets[0].spec.target_type, "linear"), 0);
122 EXPECT_TRUE(targets[0].data.empty());
123 EXPECT_EQ(targets[0].spec.sector_start, 0);
124 EXPECT_EQ(targets[0].spec.length, 1);
125 EXPECT_EQ(strcmp(targets[1].spec.target_type, "linear"), 0);
126 EXPECT_TRUE(targets[1].data.empty());
127 EXPECT_EQ(targets[1].spec.sector_start, 1);
128 EXPECT_EQ(targets[1].spec.length, 1);
129
130 // Test GetTargetType().
131 EXPECT_EQ(DeviceMapper::GetTargetType(targets[0].spec), std::string{"linear"});
132 EXPECT_EQ(DeviceMapper::GetTargetType(targets[1].spec), std::string{"linear"});
133
134 // Normally the TestDevice destructor would delete this, but at least one
135 // test should ensure that device deletion works.
136 ASSERT_TRUE(dev.Destroy());
137
138 return 0;
139 }
140