1 /*
2 * Copyright (C) 2018 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 "ueventd_parser.h"
18
19 #include <android-base/file.h>
20 #include <gtest/gtest.h>
21 #include <private/android_filesystem_config.h>
22
23 #include "firmware_handler.h"
24
25 namespace android {
26 namespace init {
27
TestSubsystems(const Subsystem & expected,const Subsystem & test)28 void TestSubsystems(const Subsystem& expected, const Subsystem& test) {
29 EXPECT_EQ(expected.name_, test.name_);
30 EXPECT_EQ(expected.devname_source_, test.devname_source_) << expected.name_;
31 EXPECT_EQ(expected.dir_name_, test.dir_name_) << expected.name_;
32 }
33
TestPermissions(const Permissions & expected,const Permissions & test)34 void TestPermissions(const Permissions& expected, const Permissions& test) {
35 EXPECT_EQ(expected.name_, test.name_);
36 EXPECT_EQ(expected.perm_, test.perm_) << expected.name_;
37 EXPECT_EQ(expected.uid_, test.uid_) << expected.name_;
38 EXPECT_EQ(expected.gid_, test.gid_) << expected.name_;
39 EXPECT_EQ(expected.prefix_, test.prefix_) << expected.name_;
40 EXPECT_EQ(expected.wildcard_, test.wildcard_) << expected.name_;
41 }
42
TestSysfsPermissions(const SysfsPermissions & expected,const SysfsPermissions & test)43 void TestSysfsPermissions(const SysfsPermissions& expected, const SysfsPermissions& test) {
44 TestPermissions(expected, test);
45 EXPECT_EQ(expected.attribute_, test.attribute_);
46 }
47
48 template <typename T, typename F>
TestVector(const T & expected,const T & test,F function)49 void TestVector(const T& expected, const T& test, F function) {
50 ASSERT_EQ(expected.size(), test.size());
51 auto expected_it = expected.begin();
52 auto test_it = test.begin();
53
54 for (; expected_it != expected.end(); ++expected_it, ++test_it) {
55 function(*expected_it, *test_it);
56 }
57 }
58
TestUeventdFile(const std::string & content,const UeventdConfiguration & expected)59 void TestUeventdFile(const std::string& content, const UeventdConfiguration& expected) {
60 TemporaryFile tf;
61 ASSERT_TRUE(tf.fd != -1);
62 ASSERT_TRUE(android::base::WriteStringToFd(content, tf.fd));
63
64 auto result = ParseConfig({tf.path});
65
66 TestVector(expected.subsystems, result.subsystems, TestSubsystems);
67 TestVector(expected.sysfs_permissions, result.sysfs_permissions, TestSysfsPermissions);
68 TestVector(expected.dev_permissions, result.dev_permissions, TestPermissions);
69 EXPECT_EQ(expected.firmware_directories, result.firmware_directories);
70 }
71
TEST(ueventd_parser,EmptyFile)72 TEST(ueventd_parser, EmptyFile) {
73 TestUeventdFile("", {});
74 }
75
TEST(ueventd_parser,Subsystems)76 TEST(ueventd_parser, Subsystems) {
77 auto ueventd_file = R"(
78 subsystem test_devname
79 devname uevent_devname
80
81 subsystem test_devpath_no_dirname
82 devname uevent_devpath
83
84 subsystem test_devname2
85 devname uevent_devname
86
87 subsystem test_devpath_dirname
88 devname uevent_devpath
89 dirname /dev/graphics
90 )";
91
92 auto subsystems = std::vector<Subsystem>{
93 {"test_devname", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
94 {"test_devpath_no_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev"},
95 {"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
96 {"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
97
98 TestUeventdFile(ueventd_file, {subsystems, {}, {}, {}, {}});
99 }
100
TEST(ueventd_parser,Permissions)101 TEST(ueventd_parser, Permissions) {
102 auto ueventd_file = R"(
103 /dev/rtc0 0640 system system
104 /dev/graphics/* 0660 root graphics
105 /dev/*/test 0660 root system
106
107 /sys/devices/platform/trusty.* trusty_version 0440 root log
108 /sys/devices/virtual/input/input enable 0660 root input
109 /sys/devices/virtual/*/input poll_delay 0660 root input
110 )";
111
112 auto permissions = std::vector<Permissions>{
113 {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM},
114 {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS},
115 {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM},
116 };
117
118 auto sysfs_permissions = std::vector<SysfsPermissions>{
119 {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG},
120 {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT},
121 {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT},
122 };
123
124 TestUeventdFile(ueventd_file, {{}, sysfs_permissions, permissions, {}, {}});
125 }
126
TEST(ueventd_parser,FirmwareDirectories)127 TEST(ueventd_parser, FirmwareDirectories) {
128 auto ueventd_file = R"(
129 firmware_directories /first/ /second /third
130 firmware_directories /more
131 )";
132
133 auto firmware_directories = std::vector<std::string>{
134 "/first/",
135 "/second",
136 "/third",
137 "/more",
138 };
139
140 TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories, {}});
141 }
142
TEST(ueventd_parser,ExternalFirmwareHandlers)143 TEST(ueventd_parser, ExternalFirmwareHandlers) {
144 auto ueventd_file = R"(
145 external_firmware_handler devpath root handler_path
146 external_firmware_handler /devices/path/firmware/something001.bin system /vendor/bin/firmware_handler.sh
147 external_firmware_handler /devices/path/firmware/something001.bin radio "/vendor/bin/firmware_handler.sh --has --arguments"
148 )";
149
150 auto external_firmware_handlers = std::vector<ExternalFirmwareHandler>{
151 {
152 "devpath",
153 AID_ROOT,
154 "handler_path",
155 },
156 {
157 "/devices/path/firmware/something001.bin",
158 AID_SYSTEM,
159 "/vendor/bin/firmware_handler.sh",
160 },
161 {
162 "/devices/path/firmware/something001.bin",
163 AID_RADIO,
164 "/vendor/bin/firmware_handler.sh --has --arguments",
165 },
166 };
167
168 TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers});
169 }
170
TEST(ueventd_parser,ExternalFirmwareHandlersDuplicate)171 TEST(ueventd_parser, ExternalFirmwareHandlersDuplicate) {
172 auto ueventd_file = R"(
173 external_firmware_handler devpath root handler_path
174 external_firmware_handler devpath root handler_path2
175 )";
176
177 auto external_firmware_handlers = std::vector<ExternalFirmwareHandler>{
178 {
179 "devpath",
180 AID_ROOT,
181 "handler_path",
182 },
183 };
184
185 TestUeventdFile(ueventd_file, {{}, {}, {}, {}, external_firmware_handlers});
186 }
187
TEST(ueventd_parser,UeventSocketRcvbufSize)188 TEST(ueventd_parser, UeventSocketRcvbufSize) {
189 auto ueventd_file = R"(
190 uevent_socket_rcvbuf_size 8k
191 uevent_socket_rcvbuf_size 8M
192 )";
193
194 TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, false, 8 * 1024 * 1024});
195 }
196
TEST(ueventd_parser,EnabledDisabledLines)197 TEST(ueventd_parser, EnabledDisabledLines) {
198 auto ueventd_file = R"(
199 modalias_handling enabled
200 parallel_restorecon enabled
201 modalias_handling disabled
202 )";
203
204 TestUeventdFile(ueventd_file, {{}, {}, {}, {}, {}, false, 0, true});
205
206 auto ueventd_file2 = R"(
207 parallel_restorecon enabled
208 modalias_handling enabled
209 parallel_restorecon disabled
210 )";
211
212 TestUeventdFile(ueventd_file2, {{}, {}, {}, {}, {}, true, 0, false});
213 }
214
TEST(ueventd_parser,AllTogether)215 TEST(ueventd_parser, AllTogether) {
216 auto ueventd_file = R"(
217
218 /dev/rtc0 0640 system system
219 firmware_directories /first/ /second /third
220 /sys/devices/platform/trusty.* trusty_version 0440 root log
221
222 subsystem test_devname
223 devname uevent_devname
224
225 /dev/graphics/* 0660 root graphics
226
227 subsystem test_devpath_no_dirname
228 devname uevent_devpath
229
230 /sys/devices/virtual/input/input enable 0660 root input
231
232 ## this is a comment
233
234 subsystem test_devname2
235 ## another comment
236 devname uevent_devname
237
238 subsystem test_devpath_dirname
239 devname uevent_devpath
240 dirname /dev/graphics
241
242 /dev/*/test 0660 root system
243 /sys/devices/virtual/*/input poll_delay 0660 root input
244 firmware_directories /more
245
246 external_firmware_handler /devices/path/firmware/firmware001.bin root /vendor/bin/touch.sh
247
248 uevent_socket_rcvbuf_size 6M
249 modalias_handling enabled
250 parallel_restorecon enabled
251
252 #ending comment
253 )";
254
255 auto subsystems = std::vector<Subsystem>{
256 {"test_devname", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
257 {"test_devpath_no_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev"},
258 {"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
259 {"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
260
261 auto permissions = std::vector<Permissions>{
262 {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM},
263 {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS},
264 {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM},
265 };
266
267 auto sysfs_permissions = std::vector<SysfsPermissions>{
268 {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG},
269 {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT},
270 {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT},
271 };
272
273 auto firmware_directories = std::vector<std::string>{
274 "/first/",
275 "/second",
276 "/third",
277 "/more",
278 };
279
280 auto external_firmware_handlers = std::vector<ExternalFirmwareHandler>{
281 {"/devices/path/firmware/firmware001.bin", AID_ROOT, "/vendor/bin/touch.sh"},
282 };
283
284 size_t uevent_socket_rcvbuf_size = 6 * 1024 * 1024;
285
286 TestUeventdFile(ueventd_file,
287 {subsystems, sysfs_permissions, permissions, firmware_directories,
288 external_firmware_handlers, true, uevent_socket_rcvbuf_size, true});
289 }
290
291 // All of these lines are ill-formed, so test that there is 0 output.
TEST(ueventd_parser,ParseErrors)292 TEST(ueventd_parser, ParseErrors) {
293 auto ueventd_file = R"(
294
295 /dev/rtc0 badmode baduidbad system
296 /dev/rtc0 0640 baduidbad system
297 /dev/rtc0 0640 system baduidbad
298 firmware_directories #no directory listed
299 /sys/devices/platform/trusty.* trusty_version badmode root log
300 /sys/devices/platform/trusty.* trusty_version 0440 baduidbad log
301 /sys/devices/platform/trusty.* trusty_version 0440 root baduidbad
302
303 uevent_socket_rcvbuf_size blah
304
305 subsystem #no name
306
307 modalias_handling
308 modalias_handling enabled enabled
309 modalias_handling blah
310
311 parallel_restorecon
312 parallel_restorecon enabled enabled
313 parallel_restorecon blah
314
315 external_firmware_handler
316 external_firmware_handler blah blah
317 external_firmware_handler blah blah blah blah
318
319 )";
320
321 TestUeventdFile(ueventd_file, {});
322 }
323
324 } // namespace init
325 } // namespace android
326