• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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