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