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 namespace android {
24 namespace init {
25
TestSubsystems(const Subsystem & expected,const Subsystem & test)26 void TestSubsystems(const Subsystem& expected, const Subsystem& test) {
27 EXPECT_EQ(expected.name_, test.name_);
28 EXPECT_EQ(expected.devname_source_, test.devname_source_) << expected.name_;
29 EXPECT_EQ(expected.dir_name_, test.dir_name_) << expected.name_;
30 }
31
TestPermissions(const Permissions & expected,const Permissions & test)32 void TestPermissions(const Permissions& expected, const Permissions& test) {
33 EXPECT_EQ(expected.name_, test.name_);
34 EXPECT_EQ(expected.perm_, test.perm_) << expected.name_;
35 EXPECT_EQ(expected.uid_, test.uid_) << expected.name_;
36 EXPECT_EQ(expected.gid_, test.gid_) << expected.name_;
37 EXPECT_EQ(expected.prefix_, test.prefix_) << expected.name_;
38 EXPECT_EQ(expected.wildcard_, test.wildcard_) << expected.name_;
39 }
40
TestSysfsPermissions(const SysfsPermissions & expected,const SysfsPermissions & test)41 void TestSysfsPermissions(const SysfsPermissions& expected, const SysfsPermissions& test) {
42 TestPermissions(expected, test);
43 EXPECT_EQ(expected.attribute_, test.attribute_);
44 }
45
46 template <typename T, typename F>
TestVector(const T & expected,const T & test,F function)47 void TestVector(const T& expected, const T& test, F function) {
48 ASSERT_EQ(expected.size(), test.size());
49 auto expected_it = expected.begin();
50 auto test_it = test.begin();
51
52 for (; expected_it != expected.end(); ++expected_it, ++test_it) {
53 function(*expected_it, *test_it);
54 }
55 }
56
TestUeventdFile(const std::string & content,const UeventdConfiguration & expected)57 void TestUeventdFile(const std::string& content, const UeventdConfiguration& expected) {
58 TemporaryFile tf;
59 ASSERT_TRUE(tf.fd != -1);
60 ASSERT_TRUE(android::base::WriteStringToFd(content, tf.fd));
61
62 auto result = ParseConfig({tf.path});
63
64 TestVector(expected.subsystems, result.subsystems, TestSubsystems);
65 TestVector(expected.sysfs_permissions, result.sysfs_permissions, TestSysfsPermissions);
66 TestVector(expected.dev_permissions, result.dev_permissions, TestPermissions);
67 EXPECT_EQ(expected.firmware_directories, result.firmware_directories);
68 }
69
TEST(ueventd_parser,EmptyFile)70 TEST(ueventd_parser, EmptyFile) {
71 TestUeventdFile("", {});
72 }
73
TEST(ueventd_parser,Subsystems)74 TEST(ueventd_parser, Subsystems) {
75 auto ueventd_file = R"(
76 subsystem test_devname
77 devname uevent_devname
78
79 subsystem test_devpath_no_dirname
80 devname uevent_devpath
81
82 subsystem test_devname2
83 devname uevent_devname
84
85 subsystem test_devpath_dirname
86 devname uevent_devpath
87 dirname /dev/graphics
88 )";
89
90 auto subsystems = std::vector<Subsystem>{
91 {"test_devname", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
92 {"test_devpath_no_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev"},
93 {"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
94 {"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
95
96 TestUeventdFile(ueventd_file, {subsystems, {}, {}, {}});
97 }
98
TEST(ueventd_parser,Permissions)99 TEST(ueventd_parser, Permissions) {
100 auto ueventd_file = R"(
101 /dev/rtc0 0640 system system
102 /dev/graphics/* 0660 root graphics
103 /dev/*/test 0660 root system
104
105 /sys/devices/platform/trusty.* trusty_version 0440 root log
106 /sys/devices/virtual/input/input enable 0660 root input
107 /sys/devices/virtual/*/input poll_delay 0660 root input
108 )";
109
110 auto permissions = std::vector<Permissions>{
111 {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM},
112 {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS},
113 {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM},
114 };
115
116 auto sysfs_permissions = std::vector<SysfsPermissions>{
117 {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG},
118 {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT},
119 {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT},
120 };
121
122 TestUeventdFile(ueventd_file, {{}, sysfs_permissions, permissions, {}});
123 }
124
TEST(ueventd_parser,FirmwareDirectories)125 TEST(ueventd_parser, FirmwareDirectories) {
126 auto ueventd_file = R"(
127 firmware_directories /first/ /second /third
128 firmware_directories /more
129 )";
130
131 auto firmware_directories = std::vector<std::string>{
132 "/first/",
133 "/second",
134 "/third",
135 "/more",
136 };
137
138 TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories});
139 }
140
TEST(ueventd_parser,UeventSocketRcvbufSize)141 TEST(ueventd_parser, UeventSocketRcvbufSize) {
142 auto ueventd_file = R"(
143 uevent_socket_rcvbuf_size 8k
144 uevent_socket_rcvbuf_size 8M
145 )";
146
147 TestUeventdFile(ueventd_file, {{}, {}, {}, {}, false, 8 * 1024 * 1024});
148 }
149
TEST(ueventd_parser,AllTogether)150 TEST(ueventd_parser, AllTogether) {
151 auto ueventd_file = R"(
152
153 /dev/rtc0 0640 system system
154 firmware_directories /first/ /second /third
155 /sys/devices/platform/trusty.* trusty_version 0440 root log
156
157 subsystem test_devname
158 devname uevent_devname
159
160 /dev/graphics/* 0660 root graphics
161
162 subsystem test_devpath_no_dirname
163 devname uevent_devpath
164
165 /sys/devices/virtual/input/input enable 0660 root input
166
167 ## this is a comment
168
169 subsystem test_devname2
170 ## another comment
171 devname uevent_devname
172
173 subsystem test_devpath_dirname
174 devname uevent_devpath
175 dirname /dev/graphics
176
177 /dev/*/test 0660 root system
178 /sys/devices/virtual/*/input poll_delay 0660 root input
179 firmware_directories /more
180
181 uevent_socket_rcvbuf_size 6M
182
183 #ending comment
184 )";
185
186 auto subsystems = std::vector<Subsystem>{
187 {"test_devname", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
188 {"test_devpath_no_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev"},
189 {"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
190 {"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
191
192 auto permissions = std::vector<Permissions>{
193 {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM},
194 {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS},
195 {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM},
196 };
197
198 auto sysfs_permissions = std::vector<SysfsPermissions>{
199 {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG},
200 {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT},
201 {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT},
202 };
203
204 auto firmware_directories = std::vector<std::string>{
205 "/first/",
206 "/second",
207 "/third",
208 "/more",
209 };
210
211 size_t uevent_socket_rcvbuf_size = 6 * 1024 * 1024;
212
213 TestUeventdFile(ueventd_file, {subsystems, sysfs_permissions, permissions, firmware_directories,
214 false, uevent_socket_rcvbuf_size});
215 }
216
217 // All of these lines are ill-formed, so test that there is 0 output.
TEST(ueventd_parser,ParseErrors)218 TEST(ueventd_parser, ParseErrors) {
219 auto ueventd_file = R"(
220
221 /dev/rtc0 badmode baduidbad system
222 /dev/rtc0 0640 baduidbad system
223 /dev/rtc0 0640 system baduidbad
224 firmware_directories #no directory listed
225 /sys/devices/platform/trusty.* trusty_version badmode root log
226 /sys/devices/platform/trusty.* trusty_version 0440 baduidbad log
227 /sys/devices/platform/trusty.* trusty_version 0440 root baduidbad
228
229 uevent_socket_rcvbuf_size blah
230
231 subsystem #no name
232
233 )";
234
235 TestUeventdFile(ueventd_file, {});
236 }
237
238 } // namespace init
239 } // namespace android
240