• 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 <string>
18 #include <vector>
19 
20 #include <android-base/file.h>
21 #include <apex_manifest.pb.h>
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 #include <linker_config.pb.h>
25 
26 #include "apex_testbase.h"
27 #include "linkerconfig/apex.h"
28 #include "linkerconfig/basecontext.h"
29 #include "linkerconfig/configwriter.h"
30 #include "linkerconfig/namespace.h"
31 #include "linkerconfig/section.h"
32 
33 using ::android::base::WriteStringToFile;
34 using ::android::linkerconfig::modules::ApexInfo;
35 using ::android::linkerconfig::modules::BaseContext;
36 using ::android::linkerconfig::modules::ConfigWriter;
37 using ::android::linkerconfig::modules::InitializeWithApex;
38 using ::android::linkerconfig::modules::Namespace;
39 using ::android::linkerconfig::modules::ScanActiveApexes;
40 using ::android::linkerconfig::modules::Section;
41 using ::apex::proto::ApexManifest;
42 using ::testing::Contains;
43 
TEST(apex_namespace,build_namespace)44 TEST(apex_namespace, build_namespace) {
45   Namespace ns("foo");
46   InitializeWithApex(ns,
47                      ApexInfo("com.android.foo",
48                               "/apex/com.android.foo",
49                               /*provide_libs=*/{},
50                               /*require_libs=*/{},
51                               /*jni_libs=*/{},
52                               /*permitted_paths=*/{},
53                               /*contributions=*/{},
54                               /*has_bin=*/false,
55                               /*has_lib=*/true,
56                               /*visible=*/false,
57                               /*has_shared_lib=*/false));
58 
59   ConfigWriter writer;
60   ns.WriteConfig(writer);
61   ASSERT_EQ(
62       "namespace.foo.isolated = false\n"
63       "namespace.foo.search.paths = /apex/com.android.foo/${LIB}\n"
64       "namespace.foo.permitted.paths = /apex/com.android.foo/${LIB}\n"
65       "namespace.foo.permitted.paths += /system/${LIB}\n"
66       "namespace.foo.asan.search.paths = /apex/com.android.foo/${LIB}\n"
67       "namespace.foo.asan.permitted.paths = /apex/com.android.foo/${LIB}\n"
68       "namespace.foo.asan.permitted.paths += /data/asan/system/${LIB}\n"
69       "namespace.foo.asan.permitted.paths += /system/${LIB}\n",
70       writer.ToString());
71 }
72 
TEST(apex_namespace,resolve_between_apex_namespaces)73 TEST(apex_namespace, resolve_between_apex_namespaces) {
74   BaseContext ctx;
75   Namespace foo("foo"), bar("bar");
76   InitializeWithApex(foo,
77                      ApexInfo("com.android.foo",
78                               "/apex/com.android.foo",
79                               /*provide_libs=*/{"foo.so"},
80                               /*require_libs=*/{"bar.so"},
81                               /*jni_libs=*/{},
82                               /*permitted_paths=*/{},
83                               /*contributions=*/{},
84                               /*has_bin=*/false,
85                               /*has_lib=*/true,
86                               /*visible=*/false,
87                               /*has_shared_lib=*/false));
88   InitializeWithApex(bar,
89                      ApexInfo("com.android.bar",
90                               "/apex/com.android.bar",
91                               /*provide_libs=*/{"bar.so"},
92                               /*require_libs=*/{},
93                               /*jni_libs=*/{},
94                               /*permitted_paths=*/{},
95                               /*contributions=*/{},
96                               /*has_bin=*/false,
97                               /*has_lib=*/true,
98                               /*visible=*/false,
99                               /*has_shared_lib=*/false));
100 
101   std::vector<Namespace> namespaces;
102   namespaces.push_back(std::move(foo));
103   namespaces.push_back(std::move(bar));
104   Section section("section", std::move(namespaces));
105 
106   auto result = section.Resolve(ctx);
107   ASSERT_RESULT_OK(result);
108 
109   // See if two namespaces are linked correctly
110   ASSERT_THAT(section.GetNamespace("foo")->GetLink("bar").GetSharedLibs(),
111               Contains("bar.so"));
112 }
113 
TEST(apex_namespace,extra_permitted_paths)114 TEST(apex_namespace, extra_permitted_paths) {
115   Namespace ns("foo");
116   InitializeWithApex(ns,
117                      ApexInfo("com.android.foo",
118                               "/apex/com.android.foo",
119                               /*provide_libs=*/{},
120                               /*require_libs=*/{},
121                               /*jni_libs=*/{},
122                               /*permitted_paths=*/{"/a", "/b/c"},
123                               /*contributions=*/{},
124                               /*has_bin=*/false,
125                               /*has_lib=*/true,
126                               /*visible=*/false,
127                               /*has_shared_lib=*/false));
128 
129   ConfigWriter writer;
130   ns.WriteConfig(writer);
131   ASSERT_EQ(
132       "namespace.foo.isolated = false\n"
133       "namespace.foo.search.paths = /apex/com.android.foo/${LIB}\n"
134       "namespace.foo.permitted.paths = /apex/com.android.foo/${LIB}\n"
135       "namespace.foo.permitted.paths += /system/${LIB}\n"
136       "namespace.foo.permitted.paths += /a\n"
137       "namespace.foo.permitted.paths += /b/c\n"
138       "namespace.foo.asan.search.paths = /apex/com.android.foo/${LIB}\n"
139       "namespace.foo.asan.permitted.paths = /apex/com.android.foo/${LIB}\n"
140       "namespace.foo.asan.permitted.paths += /data/asan/system/${LIB}\n"
141       "namespace.foo.asan.permitted.paths += /system/${LIB}\n"
142       "namespace.foo.asan.permitted.paths += /data/asan/a\n"
143       "namespace.foo.asan.permitted.paths += /a\n"
144       "namespace.foo.asan.permitted.paths += /data/asan/b/c\n"
145       "namespace.foo.asan.permitted.paths += /b/c\n",
146       writer.ToString());
147 }
148 
TEST_F(ApexTest,scan_apex_dir)149 TEST_F(ApexTest, scan_apex_dir) {
150   PrepareApex("foo", {}, {"bar.so"}, {});
151   WriteFile("/apex/foo/bin/foo", "");
152   PrepareApex("bar", {"bar.so"}, {}, {});
153   WriteFile("/apex/bar/lib64/bar.so", "");
154   PrepareApex("baz", {}, {}, {"baz.so"});
155   WriteFile("/apex/baz/lib64/baz.so", "");
156   CreateApexInfoList();
157   CreatePublicLibrariesTxt();
158 
159   auto apexes = ScanActiveApexes(root);
160   ASSERT_TRUE(apexes.ok()) << "Failed to scan active APEXes : "
161                            << apexes.error();
162   ASSERT_EQ(3U, apexes->size());
163 
164   ASSERT_THAT((*apexes)["foo"].require_libs, Contains("bar.so"));
165   ASSERT_TRUE((*apexes)["foo"].has_bin);
166   ASSERT_FALSE((*apexes)["foo"].has_lib);
167 
168   ASSERT_THAT((*apexes)["bar"].provide_libs, Contains("bar.so"));
169   ASSERT_FALSE((*apexes)["bar"].has_bin);
170   ASSERT_TRUE((*apexes)["bar"].has_lib);
171 
172   ASSERT_THAT((*apexes)["baz"].jni_libs, Contains("baz.so"));
173   ASSERT_FALSE((*apexes)["baz"].has_bin);
174   ASSERT_TRUE((*apexes)["baz"].has_lib);
175 }
176 
TEST_F(ApexTest,validate_path)177 TEST_F(ApexTest, validate_path) {
178   PrepareApex("foo", {}, {}, {});
179   CreateApexInfoList();
180   CreatePublicLibrariesTxt();
181 
182   ::android::linkerconfig::proto::LinkerConfig two_slash;
183   two_slash.add_permittedpaths("/two//slash");
184 
185   WriteFile("/apex/foo/etc/linker.config.pb", two_slash.SerializeAsString());
186   auto apexes = ScanActiveApexes(root);
187   ASSERT_FALSE(apexes.ok()) << "Two slash is not allowed from path string";
188 
189   ::android::linkerconfig::proto::LinkerConfig invalid_char;
190   invalid_char.add_permittedpaths("/path/with*/invalid/char");
191 
192   WriteFile("/apex/foo/etc/linker.config.pb", invalid_char.SerializeAsString());
193   apexes = ScanActiveApexes(root);
194   ASSERT_FALSE(apexes.ok()) << "* is invalid char for path.";
195 
196   ::android::linkerconfig::proto::LinkerConfig end_with_lib;
197   end_with_lib.add_permittedpaths("/somewhere/${LIB}");
198 
199   WriteFile("/apex/foo/etc/linker.config.pb", end_with_lib.SerializeAsString());
200   apexes = ScanActiveApexes(root);
201   ASSERT_TRUE(apexes.ok()) << "Path ends with ${LIB} should be accepted. : "
202                            << apexes.error();
203 
204   ::android::linkerconfig::proto::LinkerConfig lib_plus_char;
205   lib_plus_char.add_permittedpaths("/somewhere/${LIB}x/hw");
206 
207   WriteFile("/apex/foo/etc/linker.config.pb", lib_plus_char.SerializeAsString());
208   apexes = ScanActiveApexes(root);
209   ASSERT_FALSE(apexes.ok())
210       << "There should be no extra char after ${LIB} in path.";
211 
212   ::android::linkerconfig::proto::LinkerConfig char_plus_lib;
213   char_plus_lib.add_permittedpaths("/somewhere/x${LIB}/hw");
214 
215   WriteFile("/apex/foo/etc/linker.config.pb", char_plus_lib.SerializeAsString());
216   apexes = ScanActiveApexes(root);
217   ASSERT_FALSE(apexes.ok())
218       << "There should be no extra char before ${LIB} in path.";
219 
220   ::android::linkerconfig::proto::LinkerConfig lib_and_lib64;
221   lib_and_lib64.add_permittedpaths("/somewhere/${LIB}/hw");
222 
223   WriteFile("/apex/foo/etc/linker.config.pb", lib_and_lib64.SerializeAsString());
224   apexes = ScanActiveApexes(root);
225   ASSERT_TRUE(apexes.ok()) << "Valid path with ${LIB} should be accepted. : "
226                            << apexes.error();
227 }