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