• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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 <functional>
18 
19 #include <android-base/file.h>
20 #include <android-base/macros.h>
21 #include <android-base/unique_fd.h>
22 #include <gtest/gtest.h>
23 
24 #include <modprobe/modprobe.h>
25 
26 #include "libmodprobe_test.h"
27 
28 // Used by libmodprobe_ext_test to check if requested modules are present.
29 std::vector<std::string> test_modules;
30 
31 // Used by libmodprobe_ext_test to report which modules would have been loaded.
32 std::vector<std::string> modules_loaded;
33 
34 // Used by libmodprobe_ext_test to fake a kernel commandline
35 std::string kernel_cmdline;
36 
TEST(libmodprobe,Test)37 TEST(libmodprobe, Test) {
38     kernel_cmdline =
39             "flag1 flag2 test1.option1=50 test4.option3=\"set x\" test1.option2=60 "
40             "test8. test5.option1= test10.option1=1";
41     test_modules = {
42             "/test1.ko",  "/test2.ko",  "/test3.ko",  "/test4.ko",  "/test5.ko",
43             "/test6.ko",  "/test7.ko",  "/test8.ko",  "/test9.ko",  "/test10.ko",
44             "/test11.ko", "/test12.ko", "/test13.ko", "/test14.ko", "/test15.ko",
45     };
46 
47     std::vector<std::string> expected_modules_loaded = {
48             "/test14.ko",
49             "/test15.ko",
50             "/test3.ko",
51             "/test4.ko option3=\"set x\"",
52             "/test1.ko option1=50 option2=60",
53             "/test6.ko",
54             "/test2.ko",
55             "/test5.ko option1=",
56             "/test8.ko",
57             "/test7.ko param1=4",
58             "/test9.ko param_x=1 param_y=2 param_z=3",
59             "/test10.ko option1=1",
60             "/test12.ko",
61             "/test11.ko",
62             "/test13.ko",
63     };
64 
65     std::vector<std::string> expected_after_remove = {
66             "/test14.ko",
67             "/test15.ko",
68             "/test1.ko option1=50 option2=60",
69             "/test6.ko",
70             "/test2.ko",
71             "/test5.ko option1=",
72             "/test8.ko",
73             "/test7.ko param1=4",
74             "/test9.ko param_x=1 param_y=2 param_z=3",
75             "/test10.ko option1=1",
76             "/test12.ko",
77             "/test11.ko",
78             "/test13.ko",
79     };
80 
81     std::vector<std::string> expected_modules_blocklist_enabled = {
82             "/test1.ko option1=50 option2=60",
83             "/test6.ko",
84             "/test2.ko",
85             "/test5.ko option1=",
86             "/test8.ko",
87             "/test7.ko param1=4",
88             "/test12.ko",
89             "/test11.ko",
90             "/test13.ko",
91     };
92 
93     const std::string modules_dep =
94             "test1.ko:\n"
95             "test2.ko:\n"
96             "test3.ko:\n"
97             "test4.ko: test3.ko\n"
98             "test5.ko: test2.ko test6.ko\n"
99             "test6.ko:\n"
100             "test7.ko:\n"
101             "test8.ko:\n"
102             "test9.ko:\n"
103             "test10.ko:\n"
104             "test11.ko:\n"
105             "test12.ko:\n"
106             "test13.ko:\n"
107             "test14.ko:\n"
108             "test15.ko:\n";
109 
110     const std::string modules_softdep =
111             "softdep test7 pre: test8\n"
112             "softdep test9 post: test10\n"
113             "softdep test11 pre: test12 post: test13\n"
114             "softdep test3 pre: test141516\n";
115 
116     const std::string modules_alias =
117             "# Aliases extracted from modules themselves.\n"
118             "\n"
119             "alias test141516 test14\n"
120             "alias test141516 test15\n"
121             "alias test141516 test16\n";
122 
123     const std::string modules_options =
124             "options test7.ko param1=4\n"
125             "options test9.ko param_x=1 param_y=2 param_z=3\n"
126             "options test100.ko param_1=1\n";
127 
128     const std::string modules_blocklist =
129             "blocklist test9.ko\n"
130             "blocklist test3.ko\n";
131 
132     const std::string modules_load =
133             "test4.ko\n"
134             "test1.ko\n"
135             "test3.ko\n"
136             "test5.ko\n"
137             "test7.ko\n"
138             "test9.ko\n"
139             "test11.ko\n";
140 
141     TemporaryDir dir;
142     auto dir_path = std::string(dir.path);
143     ASSERT_TRUE(android::base::WriteStringToFile(modules_alias, dir_path + "/modules.alias", 0600,
144                                                  getuid(), getgid()));
145 
146     ASSERT_TRUE(android::base::WriteStringToFile(modules_dep, dir_path + "/modules.dep", 0600,
147                                                  getuid(), getgid()));
148     ASSERT_TRUE(android::base::WriteStringToFile(modules_softdep, dir_path + "/modules.softdep",
149                                                  0600, getuid(), getgid()));
150     ASSERT_TRUE(android::base::WriteStringToFile(modules_options, dir_path + "/modules.options",
151                                                  0600, getuid(), getgid()));
152     ASSERT_TRUE(android::base::WriteStringToFile(modules_load, dir_path + "/modules.load", 0600,
153                                                  getuid(), getgid()));
154     ASSERT_TRUE(android::base::WriteStringToFile(modules_blocklist, dir_path + "/modules.blocklist",
155                                                  0600, getuid(), getgid()));
156 
157     for (auto i = test_modules.begin(); i != test_modules.end(); ++i) {
158         *i = dir.path + *i;
159     }
160 
161     Modprobe m({dir.path}, "modules.load", false);
162     EXPECT_TRUE(m.LoadListedModules());
163 
164     GTEST_LOG_(INFO) << "Expected modules loaded (in order):";
165     for (auto i = expected_modules_loaded.begin(); i != expected_modules_loaded.end(); ++i) {
166         *i = dir.path + *i;
167         GTEST_LOG_(INFO) << "\"" << *i << "\"";
168     }
169     GTEST_LOG_(INFO) << "Actual modules loaded (in order):";
170     for (auto i = modules_loaded.begin(); i != modules_loaded.end(); ++i) {
171         GTEST_LOG_(INFO) << "\"" << *i << "\"";
172     }
173 
174     EXPECT_TRUE(modules_loaded == expected_modules_loaded);
175 
176     EXPECT_TRUE(m.GetModuleCount() == 15);
177     EXPECT_TRUE(m.Remove("test4"));
178 
179     GTEST_LOG_(INFO) << "Expected modules loaded after removing test4 (in order):";
180     for (auto i = expected_after_remove.begin(); i != expected_after_remove.end(); ++i) {
181         *i = dir.path + *i;
182         GTEST_LOG_(INFO) << "\"" << *i << "\"";
183     }
184     GTEST_LOG_(INFO) << "Actual modules loaded after removing test4 (in order):";
185     for (auto i = modules_loaded.begin(); i != modules_loaded.end(); ++i) {
186         GTEST_LOG_(INFO) << "\"" << *i << "\"";
187     }
188 
189     EXPECT_TRUE(modules_loaded == expected_after_remove);
190 
191     m = Modprobe({dir.path});
192     EXPECT_FALSE(m.LoadWithAliases("test4", true));
193     while (modules_loaded.size() > 0) EXPECT_TRUE(m.Remove(modules_loaded.front()));
194     EXPECT_TRUE(m.LoadListedModules());
195 
196     GTEST_LOG_(INFO) << "Expected modules loaded after enabling blocklist (in order):";
197     for (auto i = expected_modules_blocklist_enabled.begin();
198          i != expected_modules_blocklist_enabled.end(); ++i) {
199         *i = dir.path + *i;
200         GTEST_LOG_(INFO) << "\"" << *i << "\"";
201     }
202     GTEST_LOG_(INFO) << "Actual modules loaded with blocklist enabled (in order):";
203     for (auto i = modules_loaded.begin(); i != modules_loaded.end(); ++i) {
204         GTEST_LOG_(INFO) << "\"" << *i << "\"";
205     }
206     EXPECT_TRUE(modules_loaded == expected_modules_blocklist_enabled);
207 }
208 
TEST(libmodprobe,ModuleDepLineWithoutColonIsSkipped)209 TEST(libmodprobe, ModuleDepLineWithoutColonIsSkipped) {
210     TemporaryDir dir;
211     auto dir_path = std::string(dir.path);
212     ASSERT_TRUE(android::base::WriteStringToFile(
213             "no_colon.ko no_colon.ko\n", dir_path + "/modules.dep", 0600, getuid(), getgid()));
214 
215     kernel_cmdline = "";
216     test_modules = {dir_path + "/no_colon.ko"};
217 
218     Modprobe m({dir.path});
219     EXPECT_FALSE(m.LoadWithAliases("no_colon", true));
220 }
221