1*8d67ca89SAndroid Build Coastguard Worker /*
2*8d67ca89SAndroid Build Coastguard Worker * Copyright (C) 2017 The Android Open Source Project
3*8d67ca89SAndroid Build Coastguard Worker * All rights reserved.
4*8d67ca89SAndroid Build Coastguard Worker *
5*8d67ca89SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
6*8d67ca89SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
7*8d67ca89SAndroid Build Coastguard Worker * are met:
8*8d67ca89SAndroid Build Coastguard Worker * * Redistributions of source code must retain the above copyright
9*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
10*8d67ca89SAndroid Build Coastguard Worker * * Redistributions in binary form must reproduce the above copyright
11*8d67ca89SAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in
12*8d67ca89SAndroid Build Coastguard Worker * the documentation and/or other materials provided with the
13*8d67ca89SAndroid Build Coastguard Worker * distribution.
14*8d67ca89SAndroid Build Coastguard Worker *
15*8d67ca89SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16*8d67ca89SAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17*8d67ca89SAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18*8d67ca89SAndroid Build Coastguard Worker * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19*8d67ca89SAndroid Build Coastguard Worker * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20*8d67ca89SAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21*8d67ca89SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22*8d67ca89SAndroid Build Coastguard Worker * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23*8d67ca89SAndroid Build Coastguard Worker * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*8d67ca89SAndroid Build Coastguard Worker * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25*8d67ca89SAndroid Build Coastguard Worker * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*8d67ca89SAndroid Build Coastguard Worker * SUCH DAMAGE.
27*8d67ca89SAndroid Build Coastguard Worker */
28*8d67ca89SAndroid Build Coastguard Worker
29*8d67ca89SAndroid Build Coastguard Worker #include "linker_config.h"
30*8d67ca89SAndroid Build Coastguard Worker
31*8d67ca89SAndroid Build Coastguard Worker #include "linker_globals.h"
32*8d67ca89SAndroid Build Coastguard Worker #include "linker_debug.h"
33*8d67ca89SAndroid Build Coastguard Worker #include "linker_utils.h"
34*8d67ca89SAndroid Build Coastguard Worker
35*8d67ca89SAndroid Build Coastguard Worker #include <android-base/file.h>
36*8d67ca89SAndroid Build Coastguard Worker #include <android-base/properties.h>
37*8d67ca89SAndroid Build Coastguard Worker #include <android-base/scopeguard.h>
38*8d67ca89SAndroid Build Coastguard Worker #include <android-base/strings.h>
39*8d67ca89SAndroid Build Coastguard Worker
40*8d67ca89SAndroid Build Coastguard Worker #include <async_safe/log.h>
41*8d67ca89SAndroid Build Coastguard Worker
42*8d67ca89SAndroid Build Coastguard Worker #include <limits.h>
43*8d67ca89SAndroid Build Coastguard Worker #include <stdlib.h>
44*8d67ca89SAndroid Build Coastguard Worker #include <unistd.h>
45*8d67ca89SAndroid Build Coastguard Worker
46*8d67ca89SAndroid Build Coastguard Worker #include <string>
47*8d67ca89SAndroid Build Coastguard Worker #include <unordered_map>
48*8d67ca89SAndroid Build Coastguard Worker
49*8d67ca89SAndroid Build Coastguard Worker class ConfigParser {
50*8d67ca89SAndroid Build Coastguard Worker public:
51*8d67ca89SAndroid Build Coastguard Worker enum {
52*8d67ca89SAndroid Build Coastguard Worker kPropertyAssign,
53*8d67ca89SAndroid Build Coastguard Worker kPropertyAppend,
54*8d67ca89SAndroid Build Coastguard Worker kSection,
55*8d67ca89SAndroid Build Coastguard Worker kEndOfFile,
56*8d67ca89SAndroid Build Coastguard Worker kError,
57*8d67ca89SAndroid Build Coastguard Worker };
58*8d67ca89SAndroid Build Coastguard Worker
ConfigParser(std::string && content)59*8d67ca89SAndroid Build Coastguard Worker explicit ConfigParser(std::string&& content)
60*8d67ca89SAndroid Build Coastguard Worker : content_(std::move(content)), p_(0), lineno_(0), was_end_of_file_(false) {}
61*8d67ca89SAndroid Build Coastguard Worker
62*8d67ca89SAndroid Build Coastguard Worker /*
63*8d67ca89SAndroid Build Coastguard Worker * Possible return values
64*8d67ca89SAndroid Build Coastguard Worker * kPropertyAssign: name is set to property name and value is set to property value
65*8d67ca89SAndroid Build Coastguard Worker * kPropertyAppend: same as kPropertyAssign, but the value should be appended
66*8d67ca89SAndroid Build Coastguard Worker * kSection: name is set to section name.
67*8d67ca89SAndroid Build Coastguard Worker * kEndOfFile: reached end of file.
68*8d67ca89SAndroid Build Coastguard Worker * kError: error_msg is set.
69*8d67ca89SAndroid Build Coastguard Worker */
next_token(std::string * name,std::string * value,std::string * error_msg)70*8d67ca89SAndroid Build Coastguard Worker int next_token(std::string* name, std::string* value, std::string* error_msg) {
71*8d67ca89SAndroid Build Coastguard Worker std::string line;
72*8d67ca89SAndroid Build Coastguard Worker while(NextLine(&line)) {
73*8d67ca89SAndroid Build Coastguard Worker size_t found = line.find('#');
74*8d67ca89SAndroid Build Coastguard Worker line = android::base::Trim(line.substr(0, found));
75*8d67ca89SAndroid Build Coastguard Worker
76*8d67ca89SAndroid Build Coastguard Worker if (line.empty()) {
77*8d67ca89SAndroid Build Coastguard Worker continue;
78*8d67ca89SAndroid Build Coastguard Worker }
79*8d67ca89SAndroid Build Coastguard Worker
80*8d67ca89SAndroid Build Coastguard Worker if (line[0] == '[' && line.back() == ']') {
81*8d67ca89SAndroid Build Coastguard Worker *name = line.substr(1, line.size() - 2);
82*8d67ca89SAndroid Build Coastguard Worker return kSection;
83*8d67ca89SAndroid Build Coastguard Worker }
84*8d67ca89SAndroid Build Coastguard Worker
85*8d67ca89SAndroid Build Coastguard Worker size_t found_assign = line.find('=');
86*8d67ca89SAndroid Build Coastguard Worker size_t found_append = line.find("+=");
87*8d67ca89SAndroid Build Coastguard Worker if (found_assign != std::string::npos && found_append == std::string::npos) {
88*8d67ca89SAndroid Build Coastguard Worker *name = android::base::Trim(line.substr(0, found_assign));
89*8d67ca89SAndroid Build Coastguard Worker *value = android::base::Trim(line.substr(found_assign + 1));
90*8d67ca89SAndroid Build Coastguard Worker return kPropertyAssign;
91*8d67ca89SAndroid Build Coastguard Worker }
92*8d67ca89SAndroid Build Coastguard Worker
93*8d67ca89SAndroid Build Coastguard Worker if (found_append != std::string::npos) {
94*8d67ca89SAndroid Build Coastguard Worker *name = android::base::Trim(line.substr(0, found_append));
95*8d67ca89SAndroid Build Coastguard Worker *value = android::base::Trim(line.substr(found_append + 2));
96*8d67ca89SAndroid Build Coastguard Worker return kPropertyAppend;
97*8d67ca89SAndroid Build Coastguard Worker }
98*8d67ca89SAndroid Build Coastguard Worker
99*8d67ca89SAndroid Build Coastguard Worker *error_msg = std::string("invalid format: ") +
100*8d67ca89SAndroid Build Coastguard Worker line +
101*8d67ca89SAndroid Build Coastguard Worker ", expected \"name = property\", \"name += property\", or \"[section]\"";
102*8d67ca89SAndroid Build Coastguard Worker return kError;
103*8d67ca89SAndroid Build Coastguard Worker }
104*8d67ca89SAndroid Build Coastguard Worker
105*8d67ca89SAndroid Build Coastguard Worker // to avoid infinite cycles when programmer makes a mistake
106*8d67ca89SAndroid Build Coastguard Worker CHECK(!was_end_of_file_);
107*8d67ca89SAndroid Build Coastguard Worker was_end_of_file_ = true;
108*8d67ca89SAndroid Build Coastguard Worker return kEndOfFile;
109*8d67ca89SAndroid Build Coastguard Worker }
110*8d67ca89SAndroid Build Coastguard Worker
lineno() const111*8d67ca89SAndroid Build Coastguard Worker size_t lineno() const {
112*8d67ca89SAndroid Build Coastguard Worker return lineno_;
113*8d67ca89SAndroid Build Coastguard Worker }
114*8d67ca89SAndroid Build Coastguard Worker
115*8d67ca89SAndroid Build Coastguard Worker private:
NextLine(std::string * line)116*8d67ca89SAndroid Build Coastguard Worker bool NextLine(std::string* line) {
117*8d67ca89SAndroid Build Coastguard Worker if (p_ == std::string::npos) {
118*8d67ca89SAndroid Build Coastguard Worker return false;
119*8d67ca89SAndroid Build Coastguard Worker }
120*8d67ca89SAndroid Build Coastguard Worker
121*8d67ca89SAndroid Build Coastguard Worker size_t found = content_.find('\n', p_);
122*8d67ca89SAndroid Build Coastguard Worker if (found != std::string::npos) {
123*8d67ca89SAndroid Build Coastguard Worker *line = content_.substr(p_, found - p_);
124*8d67ca89SAndroid Build Coastguard Worker p_ = found + 1;
125*8d67ca89SAndroid Build Coastguard Worker } else {
126*8d67ca89SAndroid Build Coastguard Worker *line = content_.substr(p_);
127*8d67ca89SAndroid Build Coastguard Worker p_ = std::string::npos;
128*8d67ca89SAndroid Build Coastguard Worker }
129*8d67ca89SAndroid Build Coastguard Worker
130*8d67ca89SAndroid Build Coastguard Worker lineno_++;
131*8d67ca89SAndroid Build Coastguard Worker return true;
132*8d67ca89SAndroid Build Coastguard Worker }
133*8d67ca89SAndroid Build Coastguard Worker
134*8d67ca89SAndroid Build Coastguard Worker std::string content_;
135*8d67ca89SAndroid Build Coastguard Worker size_t p_;
136*8d67ca89SAndroid Build Coastguard Worker size_t lineno_;
137*8d67ca89SAndroid Build Coastguard Worker bool was_end_of_file_;
138*8d67ca89SAndroid Build Coastguard Worker
139*8d67ca89SAndroid Build Coastguard Worker DISALLOW_IMPLICIT_CONSTRUCTORS(ConfigParser);
140*8d67ca89SAndroid Build Coastguard Worker };
141*8d67ca89SAndroid Build Coastguard Worker
142*8d67ca89SAndroid Build Coastguard Worker class PropertyValue {
143*8d67ca89SAndroid Build Coastguard Worker public:
144*8d67ca89SAndroid Build Coastguard Worker PropertyValue() = default;
145*8d67ca89SAndroid Build Coastguard Worker
PropertyValue(std::string && value,size_t lineno)146*8d67ca89SAndroid Build Coastguard Worker PropertyValue(std::string&& value, size_t lineno)
147*8d67ca89SAndroid Build Coastguard Worker : value_(std::move(value)), lineno_(lineno) {}
148*8d67ca89SAndroid Build Coastguard Worker
value() const149*8d67ca89SAndroid Build Coastguard Worker const std::string& value() const {
150*8d67ca89SAndroid Build Coastguard Worker return value_;
151*8d67ca89SAndroid Build Coastguard Worker }
152*8d67ca89SAndroid Build Coastguard Worker
append_value(std::string && value)153*8d67ca89SAndroid Build Coastguard Worker void append_value(std::string&& value) {
154*8d67ca89SAndroid Build Coastguard Worker value_ = value_ + value;
155*8d67ca89SAndroid Build Coastguard Worker // lineno isn't updated as we might have cases like this:
156*8d67ca89SAndroid Build Coastguard Worker // property.x = blah
157*8d67ca89SAndroid Build Coastguard Worker // property.y = blah
158*8d67ca89SAndroid Build Coastguard Worker // property.x += blah
159*8d67ca89SAndroid Build Coastguard Worker }
160*8d67ca89SAndroid Build Coastguard Worker
lineno() const161*8d67ca89SAndroid Build Coastguard Worker size_t lineno() const {
162*8d67ca89SAndroid Build Coastguard Worker return lineno_;
163*8d67ca89SAndroid Build Coastguard Worker }
164*8d67ca89SAndroid Build Coastguard Worker
165*8d67ca89SAndroid Build Coastguard Worker private:
166*8d67ca89SAndroid Build Coastguard Worker std::string value_;
167*8d67ca89SAndroid Build Coastguard Worker size_t lineno_;
168*8d67ca89SAndroid Build Coastguard Worker };
169*8d67ca89SAndroid Build Coastguard Worker
create_error_msg(const char * file,size_t lineno,const std::string & msg)170*8d67ca89SAndroid Build Coastguard Worker static std::string create_error_msg(const char* file,
171*8d67ca89SAndroid Build Coastguard Worker size_t lineno,
172*8d67ca89SAndroid Build Coastguard Worker const std::string& msg) {
173*8d67ca89SAndroid Build Coastguard Worker char buf[1024];
174*8d67ca89SAndroid Build Coastguard Worker async_safe_format_buffer(buf, sizeof(buf), "%s:%zu: error: %s", file, lineno, msg.c_str());
175*8d67ca89SAndroid Build Coastguard Worker
176*8d67ca89SAndroid Build Coastguard Worker return std::string(buf);
177*8d67ca89SAndroid Build Coastguard Worker }
178*8d67ca89SAndroid Build Coastguard Worker
parse_config_file(const char * ld_config_file_path,const char * binary_realpath,std::unordered_map<std::string,PropertyValue> * properties,std::string * error_msg)179*8d67ca89SAndroid Build Coastguard Worker static bool parse_config_file(const char* ld_config_file_path,
180*8d67ca89SAndroid Build Coastguard Worker const char* binary_realpath,
181*8d67ca89SAndroid Build Coastguard Worker std::unordered_map<std::string, PropertyValue>* properties,
182*8d67ca89SAndroid Build Coastguard Worker std::string* error_msg) {
183*8d67ca89SAndroid Build Coastguard Worker std::string content;
184*8d67ca89SAndroid Build Coastguard Worker if (!android::base::ReadFileToString(ld_config_file_path, &content)) {
185*8d67ca89SAndroid Build Coastguard Worker if (errno != ENOENT) {
186*8d67ca89SAndroid Build Coastguard Worker *error_msg = std::string("error reading file \"") +
187*8d67ca89SAndroid Build Coastguard Worker ld_config_file_path + "\": " + strerror(errno);
188*8d67ca89SAndroid Build Coastguard Worker }
189*8d67ca89SAndroid Build Coastguard Worker return false;
190*8d67ca89SAndroid Build Coastguard Worker }
191*8d67ca89SAndroid Build Coastguard Worker
192*8d67ca89SAndroid Build Coastguard Worker ConfigParser cp(std::move(content));
193*8d67ca89SAndroid Build Coastguard Worker
194*8d67ca89SAndroid Build Coastguard Worker std::string section_name;
195*8d67ca89SAndroid Build Coastguard Worker
196*8d67ca89SAndroid Build Coastguard Worker while (true) {
197*8d67ca89SAndroid Build Coastguard Worker std::string name;
198*8d67ca89SAndroid Build Coastguard Worker std::string value;
199*8d67ca89SAndroid Build Coastguard Worker std::string error;
200*8d67ca89SAndroid Build Coastguard Worker
201*8d67ca89SAndroid Build Coastguard Worker int result = cp.next_token(&name, &value, &error);
202*8d67ca89SAndroid Build Coastguard Worker if (result == ConfigParser::kError) {
203*8d67ca89SAndroid Build Coastguard Worker DL_WARN("%s:%zd: warning: couldn't parse %s (ignoring this line)",
204*8d67ca89SAndroid Build Coastguard Worker ld_config_file_path,
205*8d67ca89SAndroid Build Coastguard Worker cp.lineno(),
206*8d67ca89SAndroid Build Coastguard Worker error.c_str());
207*8d67ca89SAndroid Build Coastguard Worker continue;
208*8d67ca89SAndroid Build Coastguard Worker }
209*8d67ca89SAndroid Build Coastguard Worker
210*8d67ca89SAndroid Build Coastguard Worker if (result == ConfigParser::kSection || result == ConfigParser::kEndOfFile) {
211*8d67ca89SAndroid Build Coastguard Worker return false;
212*8d67ca89SAndroid Build Coastguard Worker }
213*8d67ca89SAndroid Build Coastguard Worker
214*8d67ca89SAndroid Build Coastguard Worker if (result == ConfigParser::kPropertyAssign) {
215*8d67ca89SAndroid Build Coastguard Worker if (!android::base::StartsWith(name, "dir.")) {
216*8d67ca89SAndroid Build Coastguard Worker DL_WARN("%s:%zd: warning: unexpected property name \"%s\", "
217*8d67ca89SAndroid Build Coastguard Worker "expected format dir.<section_name> (ignoring this line)",
218*8d67ca89SAndroid Build Coastguard Worker ld_config_file_path,
219*8d67ca89SAndroid Build Coastguard Worker cp.lineno(),
220*8d67ca89SAndroid Build Coastguard Worker name.c_str());
221*8d67ca89SAndroid Build Coastguard Worker continue;
222*8d67ca89SAndroid Build Coastguard Worker }
223*8d67ca89SAndroid Build Coastguard Worker
224*8d67ca89SAndroid Build Coastguard Worker // remove trailing '/'
225*8d67ca89SAndroid Build Coastguard Worker while (!value.empty() && value.back() == '/') {
226*8d67ca89SAndroid Build Coastguard Worker value.pop_back();
227*8d67ca89SAndroid Build Coastguard Worker }
228*8d67ca89SAndroid Build Coastguard Worker
229*8d67ca89SAndroid Build Coastguard Worker if (value.empty()) {
230*8d67ca89SAndroid Build Coastguard Worker DL_WARN("%s:%zd: warning: property value is empty (ignoring this line)",
231*8d67ca89SAndroid Build Coastguard Worker ld_config_file_path,
232*8d67ca89SAndroid Build Coastguard Worker cp.lineno());
233*8d67ca89SAndroid Build Coastguard Worker continue;
234*8d67ca89SAndroid Build Coastguard Worker }
235*8d67ca89SAndroid Build Coastguard Worker
236*8d67ca89SAndroid Build Coastguard Worker // If the path can be resolved, resolve it
237*8d67ca89SAndroid Build Coastguard Worker char buf[PATH_MAX];
238*8d67ca89SAndroid Build Coastguard Worker std::string resolved_path;
239*8d67ca89SAndroid Build Coastguard Worker if (access(value.c_str(), R_OK) != 0) {
240*8d67ca89SAndroid Build Coastguard Worker if (errno == ENOENT) {
241*8d67ca89SAndroid Build Coastguard Worker // no need to test for non-existing path. skip.
242*8d67ca89SAndroid Build Coastguard Worker continue;
243*8d67ca89SAndroid Build Coastguard Worker }
244*8d67ca89SAndroid Build Coastguard Worker // If not accessible, don't call realpath as it will just cause
245*8d67ca89SAndroid Build Coastguard Worker // SELinux denial spam. Use the path unresolved.
246*8d67ca89SAndroid Build Coastguard Worker resolved_path = value;
247*8d67ca89SAndroid Build Coastguard Worker } else if (realpath(value.c_str(), buf)) {
248*8d67ca89SAndroid Build Coastguard Worker resolved_path = buf;
249*8d67ca89SAndroid Build Coastguard Worker } else {
250*8d67ca89SAndroid Build Coastguard Worker // realpath is expected to fail with EPERM in some situations, so log
251*8d67ca89SAndroid Build Coastguard Worker // the failure with INFO rather than DL_WARN. e.g. A binary in
252*8d67ca89SAndroid Build Coastguard Worker // /data/local/tmp may attempt to stat /postinstall. See
253*8d67ca89SAndroid Build Coastguard Worker // http://b/120996057.
254*8d67ca89SAndroid Build Coastguard Worker LD_DEBUG(any, "%s:%zd: warning: path \"%s\" couldn't be resolved: %m",
255*8d67ca89SAndroid Build Coastguard Worker ld_config_file_path, cp.lineno(), value.c_str());
256*8d67ca89SAndroid Build Coastguard Worker resolved_path = value;
257*8d67ca89SAndroid Build Coastguard Worker }
258*8d67ca89SAndroid Build Coastguard Worker
259*8d67ca89SAndroid Build Coastguard Worker if (file_is_under_dir(binary_realpath, resolved_path)) {
260*8d67ca89SAndroid Build Coastguard Worker section_name = name.substr(4);
261*8d67ca89SAndroid Build Coastguard Worker break;
262*8d67ca89SAndroid Build Coastguard Worker }
263*8d67ca89SAndroid Build Coastguard Worker }
264*8d67ca89SAndroid Build Coastguard Worker }
265*8d67ca89SAndroid Build Coastguard Worker
266*8d67ca89SAndroid Build Coastguard Worker LD_DEBUG(any, "[ Using config section \"%s\" ]", section_name.c_str());
267*8d67ca89SAndroid Build Coastguard Worker
268*8d67ca89SAndroid Build Coastguard Worker // skip everything until we meet a correct section
269*8d67ca89SAndroid Build Coastguard Worker while (true) {
270*8d67ca89SAndroid Build Coastguard Worker std::string name;
271*8d67ca89SAndroid Build Coastguard Worker std::string value;
272*8d67ca89SAndroid Build Coastguard Worker std::string error;
273*8d67ca89SAndroid Build Coastguard Worker
274*8d67ca89SAndroid Build Coastguard Worker int result = cp.next_token(&name, &value, &error);
275*8d67ca89SAndroid Build Coastguard Worker
276*8d67ca89SAndroid Build Coastguard Worker if (result == ConfigParser::kSection && name == section_name) {
277*8d67ca89SAndroid Build Coastguard Worker break;
278*8d67ca89SAndroid Build Coastguard Worker }
279*8d67ca89SAndroid Build Coastguard Worker
280*8d67ca89SAndroid Build Coastguard Worker if (result == ConfigParser::kEndOfFile) {
281*8d67ca89SAndroid Build Coastguard Worker *error_msg = create_error_msg(ld_config_file_path,
282*8d67ca89SAndroid Build Coastguard Worker cp.lineno(),
283*8d67ca89SAndroid Build Coastguard Worker std::string("section \"") + section_name + "\" not found");
284*8d67ca89SAndroid Build Coastguard Worker return false;
285*8d67ca89SAndroid Build Coastguard Worker }
286*8d67ca89SAndroid Build Coastguard Worker }
287*8d67ca89SAndroid Build Coastguard Worker
288*8d67ca89SAndroid Build Coastguard Worker // found the section - parse it
289*8d67ca89SAndroid Build Coastguard Worker while (true) {
290*8d67ca89SAndroid Build Coastguard Worker std::string name;
291*8d67ca89SAndroid Build Coastguard Worker std::string value;
292*8d67ca89SAndroid Build Coastguard Worker std::string error;
293*8d67ca89SAndroid Build Coastguard Worker
294*8d67ca89SAndroid Build Coastguard Worker int result = cp.next_token(&name, &value, &error);
295*8d67ca89SAndroid Build Coastguard Worker
296*8d67ca89SAndroid Build Coastguard Worker if (result == ConfigParser::kEndOfFile || result == ConfigParser::kSection) {
297*8d67ca89SAndroid Build Coastguard Worker break;
298*8d67ca89SAndroid Build Coastguard Worker }
299*8d67ca89SAndroid Build Coastguard Worker
300*8d67ca89SAndroid Build Coastguard Worker if (result == ConfigParser::kPropertyAssign) {
301*8d67ca89SAndroid Build Coastguard Worker if (properties->contains(name)) {
302*8d67ca89SAndroid Build Coastguard Worker DL_WARN("%s:%zd: warning: redefining property \"%s\" (overriding previous value)",
303*8d67ca89SAndroid Build Coastguard Worker ld_config_file_path,
304*8d67ca89SAndroid Build Coastguard Worker cp.lineno(),
305*8d67ca89SAndroid Build Coastguard Worker name.c_str());
306*8d67ca89SAndroid Build Coastguard Worker }
307*8d67ca89SAndroid Build Coastguard Worker
308*8d67ca89SAndroid Build Coastguard Worker (*properties)[name] = PropertyValue(std::move(value), cp.lineno());
309*8d67ca89SAndroid Build Coastguard Worker } else if (result == ConfigParser::kPropertyAppend) {
310*8d67ca89SAndroid Build Coastguard Worker if (!properties->contains(name)) {
311*8d67ca89SAndroid Build Coastguard Worker DL_WARN("%s:%zd: warning: appending to undefined property \"%s\" (treating as assignment)",
312*8d67ca89SAndroid Build Coastguard Worker ld_config_file_path,
313*8d67ca89SAndroid Build Coastguard Worker cp.lineno(),
314*8d67ca89SAndroid Build Coastguard Worker name.c_str());
315*8d67ca89SAndroid Build Coastguard Worker (*properties)[name] = PropertyValue(std::move(value), cp.lineno());
316*8d67ca89SAndroid Build Coastguard Worker } else {
317*8d67ca89SAndroid Build Coastguard Worker if (android::base::EndsWith(name, ".links") ||
318*8d67ca89SAndroid Build Coastguard Worker android::base::EndsWith(name, ".namespaces")) {
319*8d67ca89SAndroid Build Coastguard Worker value = "," + value;
320*8d67ca89SAndroid Build Coastguard Worker (*properties)[name].append_value(std::move(value));
321*8d67ca89SAndroid Build Coastguard Worker } else if (android::base::EndsWith(name, ".paths") ||
322*8d67ca89SAndroid Build Coastguard Worker android::base::EndsWith(name, ".shared_libs") ||
323*8d67ca89SAndroid Build Coastguard Worker android::base::EndsWith(name, ".whitelisted") ||
324*8d67ca89SAndroid Build Coastguard Worker android::base::EndsWith(name, ".allowed_libs")) {
325*8d67ca89SAndroid Build Coastguard Worker value = ":" + value;
326*8d67ca89SAndroid Build Coastguard Worker (*properties)[name].append_value(std::move(value));
327*8d67ca89SAndroid Build Coastguard Worker } else {
328*8d67ca89SAndroid Build Coastguard Worker DL_WARN("%s:%zd: warning: += isn't allowed for property \"%s\" (ignoring)",
329*8d67ca89SAndroid Build Coastguard Worker ld_config_file_path,
330*8d67ca89SAndroid Build Coastguard Worker cp.lineno(),
331*8d67ca89SAndroid Build Coastguard Worker name.c_str());
332*8d67ca89SAndroid Build Coastguard Worker }
333*8d67ca89SAndroid Build Coastguard Worker }
334*8d67ca89SAndroid Build Coastguard Worker }
335*8d67ca89SAndroid Build Coastguard Worker
336*8d67ca89SAndroid Build Coastguard Worker if (result == ConfigParser::kError) {
337*8d67ca89SAndroid Build Coastguard Worker DL_WARN("%s:%zd: warning: couldn't parse %s (ignoring this line)",
338*8d67ca89SAndroid Build Coastguard Worker ld_config_file_path,
339*8d67ca89SAndroid Build Coastguard Worker cp.lineno(),
340*8d67ca89SAndroid Build Coastguard Worker error.c_str());
341*8d67ca89SAndroid Build Coastguard Worker continue;
342*8d67ca89SAndroid Build Coastguard Worker }
343*8d67ca89SAndroid Build Coastguard Worker }
344*8d67ca89SAndroid Build Coastguard Worker
345*8d67ca89SAndroid Build Coastguard Worker return true;
346*8d67ca89SAndroid Build Coastguard Worker }
347*8d67ca89SAndroid Build Coastguard Worker
348*8d67ca89SAndroid Build Coastguard Worker static Config g_config;
349*8d67ca89SAndroid Build Coastguard Worker
350*8d67ca89SAndroid Build Coastguard Worker static constexpr const char* kDefaultConfigName = "default";
351*8d67ca89SAndroid Build Coastguard Worker static constexpr const char* kPropertyAdditionalNamespaces = "additional.namespaces";
352*8d67ca89SAndroid Build Coastguard Worker
353*8d67ca89SAndroid Build Coastguard Worker class Properties {
354*8d67ca89SAndroid Build Coastguard Worker public:
Properties(std::unordered_map<std::string,PropertyValue> && properties)355*8d67ca89SAndroid Build Coastguard Worker explicit Properties(std::unordered_map<std::string, PropertyValue>&& properties)
356*8d67ca89SAndroid Build Coastguard Worker : properties_(std::move(properties)), target_sdk_version_(__ANDROID_API__) {}
357*8d67ca89SAndroid Build Coastguard Worker
get_strings(const std::string & name,size_t * lineno=nullptr) const358*8d67ca89SAndroid Build Coastguard Worker std::vector<std::string> get_strings(const std::string& name, size_t* lineno = nullptr) const {
359*8d67ca89SAndroid Build Coastguard Worker auto it = find_property(name, lineno);
360*8d67ca89SAndroid Build Coastguard Worker if (it == properties_.end()) {
361*8d67ca89SAndroid Build Coastguard Worker // return empty vector
362*8d67ca89SAndroid Build Coastguard Worker return std::vector<std::string>();
363*8d67ca89SAndroid Build Coastguard Worker }
364*8d67ca89SAndroid Build Coastguard Worker
365*8d67ca89SAndroid Build Coastguard Worker std::vector<std::string> strings = android::base::Split(it->second.value(), ",");
366*8d67ca89SAndroid Build Coastguard Worker
367*8d67ca89SAndroid Build Coastguard Worker for (size_t i = 0; i < strings.size(); ++i) {
368*8d67ca89SAndroid Build Coastguard Worker strings[i] = android::base::Trim(strings[i]);
369*8d67ca89SAndroid Build Coastguard Worker }
370*8d67ca89SAndroid Build Coastguard Worker
371*8d67ca89SAndroid Build Coastguard Worker return strings;
372*8d67ca89SAndroid Build Coastguard Worker }
373*8d67ca89SAndroid Build Coastguard Worker
get_bool(const std::string & name,size_t * lineno=nullptr) const374*8d67ca89SAndroid Build Coastguard Worker bool get_bool(const std::string& name, size_t* lineno = nullptr) const {
375*8d67ca89SAndroid Build Coastguard Worker auto it = find_property(name, lineno);
376*8d67ca89SAndroid Build Coastguard Worker if (it == properties_.end()) {
377*8d67ca89SAndroid Build Coastguard Worker return false;
378*8d67ca89SAndroid Build Coastguard Worker }
379*8d67ca89SAndroid Build Coastguard Worker
380*8d67ca89SAndroid Build Coastguard Worker return it->second.value() == "true";
381*8d67ca89SAndroid Build Coastguard Worker }
382*8d67ca89SAndroid Build Coastguard Worker
get_string(const std::string & name,size_t * lineno=nullptr) const383*8d67ca89SAndroid Build Coastguard Worker std::string get_string(const std::string& name, size_t* lineno = nullptr) const {
384*8d67ca89SAndroid Build Coastguard Worker auto it = find_property(name, lineno);
385*8d67ca89SAndroid Build Coastguard Worker return (it == properties_.end()) ? "" : it->second.value();
386*8d67ca89SAndroid Build Coastguard Worker }
387*8d67ca89SAndroid Build Coastguard Worker
get_paths(const std::string & name,bool resolve,size_t * lineno=nullptr)388*8d67ca89SAndroid Build Coastguard Worker std::vector<std::string> get_paths(const std::string& name, bool resolve, size_t* lineno = nullptr) {
389*8d67ca89SAndroid Build Coastguard Worker std::string paths_str = get_string(name, lineno);
390*8d67ca89SAndroid Build Coastguard Worker
391*8d67ca89SAndroid Build Coastguard Worker std::vector<std::string> paths;
392*8d67ca89SAndroid Build Coastguard Worker split_path(paths_str.c_str(), ":", &paths);
393*8d67ca89SAndroid Build Coastguard Worker
394*8d67ca89SAndroid Build Coastguard Worker std::vector<std::pair<std::string, std::string>> params;
395*8d67ca89SAndroid Build Coastguard Worker params.push_back({ "LIB", kLibPath });
396*8d67ca89SAndroid Build Coastguard Worker if (target_sdk_version_ != 0) {
397*8d67ca89SAndroid Build Coastguard Worker char buf[16];
398*8d67ca89SAndroid Build Coastguard Worker async_safe_format_buffer(buf, sizeof(buf), "%d", target_sdk_version_);
399*8d67ca89SAndroid Build Coastguard Worker params.push_back({ "SDK_VER", buf });
400*8d67ca89SAndroid Build Coastguard Worker }
401*8d67ca89SAndroid Build Coastguard Worker
402*8d67ca89SAndroid Build Coastguard Worker static std::string vndk_ver = Config::get_vndk_version_string('-');
403*8d67ca89SAndroid Build Coastguard Worker params.push_back({ "VNDK_VER", vndk_ver });
404*8d67ca89SAndroid Build Coastguard Worker static std::string vndk_apex_ver = Config::get_vndk_version_string('v');
405*8d67ca89SAndroid Build Coastguard Worker params.push_back({ "VNDK_APEX_VER", vndk_apex_ver });
406*8d67ca89SAndroid Build Coastguard Worker
407*8d67ca89SAndroid Build Coastguard Worker for (auto& path : paths) {
408*8d67ca89SAndroid Build Coastguard Worker format_string(&path, params);
409*8d67ca89SAndroid Build Coastguard Worker }
410*8d67ca89SAndroid Build Coastguard Worker
411*8d67ca89SAndroid Build Coastguard Worker if (resolve) {
412*8d67ca89SAndroid Build Coastguard Worker std::vector<std::string> resolved_paths;
413*8d67ca89SAndroid Build Coastguard Worker for (const auto& path : paths) {
414*8d67ca89SAndroid Build Coastguard Worker if (path.empty()) {
415*8d67ca89SAndroid Build Coastguard Worker continue;
416*8d67ca89SAndroid Build Coastguard Worker }
417*8d67ca89SAndroid Build Coastguard Worker // this is single threaded. no need to lock
418*8d67ca89SAndroid Build Coastguard Worker auto cached = resolved_paths_.find(path);
419*8d67ca89SAndroid Build Coastguard Worker if (cached == resolved_paths_.end()) {
420*8d67ca89SAndroid Build Coastguard Worker resolved_paths_[path] = resolve_path(path);
421*8d67ca89SAndroid Build Coastguard Worker cached = resolved_paths_.find(path);
422*8d67ca89SAndroid Build Coastguard Worker }
423*8d67ca89SAndroid Build Coastguard Worker CHECK(cached != resolved_paths_.end());
424*8d67ca89SAndroid Build Coastguard Worker if (cached->second.empty()) {
425*8d67ca89SAndroid Build Coastguard Worker continue;
426*8d67ca89SAndroid Build Coastguard Worker }
427*8d67ca89SAndroid Build Coastguard Worker resolved_paths.push_back(cached->second);
428*8d67ca89SAndroid Build Coastguard Worker }
429*8d67ca89SAndroid Build Coastguard Worker
430*8d67ca89SAndroid Build Coastguard Worker return resolved_paths;
431*8d67ca89SAndroid Build Coastguard Worker } else {
432*8d67ca89SAndroid Build Coastguard Worker return paths;
433*8d67ca89SAndroid Build Coastguard Worker }
434*8d67ca89SAndroid Build Coastguard Worker }
435*8d67ca89SAndroid Build Coastguard Worker
set_target_sdk_version(int target_sdk_version)436*8d67ca89SAndroid Build Coastguard Worker void set_target_sdk_version(int target_sdk_version) {
437*8d67ca89SAndroid Build Coastguard Worker target_sdk_version_ = target_sdk_version;
438*8d67ca89SAndroid Build Coastguard Worker }
439*8d67ca89SAndroid Build Coastguard Worker
440*8d67ca89SAndroid Build Coastguard Worker private:
441*8d67ca89SAndroid Build Coastguard Worker std::unordered_map<std::string, PropertyValue>::const_iterator
find_property(const std::string & name,size_t * lineno) const442*8d67ca89SAndroid Build Coastguard Worker find_property(const std::string& name, size_t* lineno) const {
443*8d67ca89SAndroid Build Coastguard Worker auto it = properties_.find(name);
444*8d67ca89SAndroid Build Coastguard Worker if (it != properties_.end() && lineno != nullptr) {
445*8d67ca89SAndroid Build Coastguard Worker *lineno = it->second.lineno();
446*8d67ca89SAndroid Build Coastguard Worker }
447*8d67ca89SAndroid Build Coastguard Worker
448*8d67ca89SAndroid Build Coastguard Worker return it;
449*8d67ca89SAndroid Build Coastguard Worker }
450*8d67ca89SAndroid Build Coastguard Worker std::unordered_map<std::string, PropertyValue> properties_;
451*8d67ca89SAndroid Build Coastguard Worker std::unordered_map<std::string, std::string> resolved_paths_;
452*8d67ca89SAndroid Build Coastguard Worker int target_sdk_version_;
453*8d67ca89SAndroid Build Coastguard Worker
454*8d67ca89SAndroid Build Coastguard Worker DISALLOW_IMPLICIT_CONSTRUCTORS(Properties);
455*8d67ca89SAndroid Build Coastguard Worker };
456*8d67ca89SAndroid Build Coastguard Worker
read_binary_config(const char * ld_config_file_path,const char * binary_realpath,bool is_asan,bool is_hwasan,const Config ** config,std::string * error_msg)457*8d67ca89SAndroid Build Coastguard Worker bool Config::read_binary_config(const char* ld_config_file_path,
458*8d67ca89SAndroid Build Coastguard Worker const char* binary_realpath,
459*8d67ca89SAndroid Build Coastguard Worker bool is_asan,
460*8d67ca89SAndroid Build Coastguard Worker bool is_hwasan,
461*8d67ca89SAndroid Build Coastguard Worker const Config** config,
462*8d67ca89SAndroid Build Coastguard Worker std::string* error_msg) {
463*8d67ca89SAndroid Build Coastguard Worker g_config.clear();
464*8d67ca89SAndroid Build Coastguard Worker
465*8d67ca89SAndroid Build Coastguard Worker std::unordered_map<std::string, PropertyValue> property_map;
466*8d67ca89SAndroid Build Coastguard Worker if (!parse_config_file(ld_config_file_path, binary_realpath, &property_map, error_msg)) {
467*8d67ca89SAndroid Build Coastguard Worker return false;
468*8d67ca89SAndroid Build Coastguard Worker }
469*8d67ca89SAndroid Build Coastguard Worker
470*8d67ca89SAndroid Build Coastguard Worker Properties properties(std::move(property_map));
471*8d67ca89SAndroid Build Coastguard Worker
472*8d67ca89SAndroid Build Coastguard Worker auto failure_guard = android::base::make_scope_guard([] { g_config.clear(); });
473*8d67ca89SAndroid Build Coastguard Worker
474*8d67ca89SAndroid Build Coastguard Worker std::unordered_map<std::string, NamespaceConfig*> namespace_configs;
475*8d67ca89SAndroid Build Coastguard Worker
476*8d67ca89SAndroid Build Coastguard Worker namespace_configs[kDefaultConfigName] = g_config.create_namespace_config(kDefaultConfigName);
477*8d67ca89SAndroid Build Coastguard Worker
478*8d67ca89SAndroid Build Coastguard Worker std::vector<std::string> additional_namespaces = properties.get_strings(kPropertyAdditionalNamespaces);
479*8d67ca89SAndroid Build Coastguard Worker for (const auto& name : additional_namespaces) {
480*8d67ca89SAndroid Build Coastguard Worker namespace_configs[name] = g_config.create_namespace_config(name);
481*8d67ca89SAndroid Build Coastguard Worker }
482*8d67ca89SAndroid Build Coastguard Worker
483*8d67ca89SAndroid Build Coastguard Worker bool versioning_enabled = properties.get_bool("enable.target.sdk.version");
484*8d67ca89SAndroid Build Coastguard Worker int target_sdk_version = __ANDROID_API__;
485*8d67ca89SAndroid Build Coastguard Worker if (versioning_enabled) {
486*8d67ca89SAndroid Build Coastguard Worker std::string version_file = dirname(binary_realpath) + "/.version";
487*8d67ca89SAndroid Build Coastguard Worker std::string content;
488*8d67ca89SAndroid Build Coastguard Worker if (!android::base::ReadFileToString(version_file, &content)) {
489*8d67ca89SAndroid Build Coastguard Worker if (errno != ENOENT) {
490*8d67ca89SAndroid Build Coastguard Worker *error_msg = std::string("error reading version file \"") +
491*8d67ca89SAndroid Build Coastguard Worker version_file + "\": " + strerror(errno);
492*8d67ca89SAndroid Build Coastguard Worker return false;
493*8d67ca89SAndroid Build Coastguard Worker }
494*8d67ca89SAndroid Build Coastguard Worker } else {
495*8d67ca89SAndroid Build Coastguard Worker content = android::base::Trim(content);
496*8d67ca89SAndroid Build Coastguard Worker errno = 0;
497*8d67ca89SAndroid Build Coastguard Worker char* end = nullptr;
498*8d67ca89SAndroid Build Coastguard Worker const char* content_str = content.c_str();
499*8d67ca89SAndroid Build Coastguard Worker int result = strtol(content_str, &end, 10);
500*8d67ca89SAndroid Build Coastguard Worker if (errno == 0 && *end == '\0' && result > 0) {
501*8d67ca89SAndroid Build Coastguard Worker target_sdk_version = result;
502*8d67ca89SAndroid Build Coastguard Worker properties.set_target_sdk_version(target_sdk_version);
503*8d67ca89SAndroid Build Coastguard Worker } else {
504*8d67ca89SAndroid Build Coastguard Worker *error_msg = std::string("invalid version \"") + version_file + "\": \"" + content +"\"";
505*8d67ca89SAndroid Build Coastguard Worker return false;
506*8d67ca89SAndroid Build Coastguard Worker }
507*8d67ca89SAndroid Build Coastguard Worker }
508*8d67ca89SAndroid Build Coastguard Worker }
509*8d67ca89SAndroid Build Coastguard Worker
510*8d67ca89SAndroid Build Coastguard Worker g_config.set_target_sdk_version(target_sdk_version);
511*8d67ca89SAndroid Build Coastguard Worker
512*8d67ca89SAndroid Build Coastguard Worker for (const auto& ns_config_it : namespace_configs) {
513*8d67ca89SAndroid Build Coastguard Worker auto& name = ns_config_it.first;
514*8d67ca89SAndroid Build Coastguard Worker NamespaceConfig* ns_config = ns_config_it.second;
515*8d67ca89SAndroid Build Coastguard Worker
516*8d67ca89SAndroid Build Coastguard Worker std::string property_name_prefix = std::string("namespace.") + name;
517*8d67ca89SAndroid Build Coastguard Worker
518*8d67ca89SAndroid Build Coastguard Worker size_t lineno = 0;
519*8d67ca89SAndroid Build Coastguard Worker std::vector<std::string> linked_namespaces =
520*8d67ca89SAndroid Build Coastguard Worker properties.get_strings(property_name_prefix + ".links", &lineno);
521*8d67ca89SAndroid Build Coastguard Worker
522*8d67ca89SAndroid Build Coastguard Worker for (const auto& linked_ns_name : linked_namespaces) {
523*8d67ca89SAndroid Build Coastguard Worker if (!namespace_configs.contains(linked_ns_name)) {
524*8d67ca89SAndroid Build Coastguard Worker *error_msg = create_error_msg(ld_config_file_path,
525*8d67ca89SAndroid Build Coastguard Worker lineno,
526*8d67ca89SAndroid Build Coastguard Worker std::string("undefined namespace: ") + linked_ns_name);
527*8d67ca89SAndroid Build Coastguard Worker return false;
528*8d67ca89SAndroid Build Coastguard Worker }
529*8d67ca89SAndroid Build Coastguard Worker
530*8d67ca89SAndroid Build Coastguard Worker bool allow_all_shared_libs = properties.get_bool(property_name_prefix + ".link." +
531*8d67ca89SAndroid Build Coastguard Worker linked_ns_name + ".allow_all_shared_libs");
532*8d67ca89SAndroid Build Coastguard Worker
533*8d67ca89SAndroid Build Coastguard Worker std::string shared_libs = properties.get_string(property_name_prefix +
534*8d67ca89SAndroid Build Coastguard Worker ".link." +
535*8d67ca89SAndroid Build Coastguard Worker linked_ns_name +
536*8d67ca89SAndroid Build Coastguard Worker ".shared_libs", &lineno);
537*8d67ca89SAndroid Build Coastguard Worker
538*8d67ca89SAndroid Build Coastguard Worker if (!allow_all_shared_libs && shared_libs.empty()) {
539*8d67ca89SAndroid Build Coastguard Worker *error_msg = create_error_msg(ld_config_file_path,
540*8d67ca89SAndroid Build Coastguard Worker lineno,
541*8d67ca89SAndroid Build Coastguard Worker std::string("list of shared_libs for ") +
542*8d67ca89SAndroid Build Coastguard Worker name +
543*8d67ca89SAndroid Build Coastguard Worker "->" +
544*8d67ca89SAndroid Build Coastguard Worker linked_ns_name +
545*8d67ca89SAndroid Build Coastguard Worker " link is not specified or is empty.");
546*8d67ca89SAndroid Build Coastguard Worker return false;
547*8d67ca89SAndroid Build Coastguard Worker }
548*8d67ca89SAndroid Build Coastguard Worker
549*8d67ca89SAndroid Build Coastguard Worker if (allow_all_shared_libs && !shared_libs.empty()) {
550*8d67ca89SAndroid Build Coastguard Worker *error_msg = create_error_msg(ld_config_file_path, lineno,
551*8d67ca89SAndroid Build Coastguard Worker std::string("both shared_libs and allow_all_shared_libs "
552*8d67ca89SAndroid Build Coastguard Worker "are set for ") +
553*8d67ca89SAndroid Build Coastguard Worker name + "->" + linked_ns_name + " link.");
554*8d67ca89SAndroid Build Coastguard Worker return false;
555*8d67ca89SAndroid Build Coastguard Worker }
556*8d67ca89SAndroid Build Coastguard Worker
557*8d67ca89SAndroid Build Coastguard Worker ns_config->add_namespace_link(linked_ns_name, shared_libs, allow_all_shared_libs);
558*8d67ca89SAndroid Build Coastguard Worker }
559*8d67ca89SAndroid Build Coastguard Worker
560*8d67ca89SAndroid Build Coastguard Worker ns_config->set_isolated(properties.get_bool(property_name_prefix + ".isolated"));
561*8d67ca89SAndroid Build Coastguard Worker ns_config->set_visible(properties.get_bool(property_name_prefix + ".visible"));
562*8d67ca89SAndroid Build Coastguard Worker
563*8d67ca89SAndroid Build Coastguard Worker std::string allowed_libs =
564*8d67ca89SAndroid Build Coastguard Worker properties.get_string(property_name_prefix + ".whitelisted", &lineno);
565*8d67ca89SAndroid Build Coastguard Worker const std::string libs = properties.get_string(property_name_prefix + ".allowed_libs", &lineno);
566*8d67ca89SAndroid Build Coastguard Worker if (!allowed_libs.empty() && !libs.empty()) {
567*8d67ca89SAndroid Build Coastguard Worker allowed_libs += ":";
568*8d67ca89SAndroid Build Coastguard Worker }
569*8d67ca89SAndroid Build Coastguard Worker allowed_libs += libs;
570*8d67ca89SAndroid Build Coastguard Worker if (!allowed_libs.empty()) {
571*8d67ca89SAndroid Build Coastguard Worker ns_config->set_allowed_libs(android::base::Split(allowed_libs, ":"));
572*8d67ca89SAndroid Build Coastguard Worker }
573*8d67ca89SAndroid Build Coastguard Worker
574*8d67ca89SAndroid Build Coastguard Worker // these are affected by is_asan flag
575*8d67ca89SAndroid Build Coastguard Worker if (is_asan) {
576*8d67ca89SAndroid Build Coastguard Worker property_name_prefix += ".asan";
577*8d67ca89SAndroid Build Coastguard Worker } else if (is_hwasan) {
578*8d67ca89SAndroid Build Coastguard Worker property_name_prefix += ".hwasan";
579*8d67ca89SAndroid Build Coastguard Worker }
580*8d67ca89SAndroid Build Coastguard Worker
581*8d67ca89SAndroid Build Coastguard Worker // search paths are resolved (canonicalized). This is required mainly for
582*8d67ca89SAndroid Build Coastguard Worker // the case when /vendor is a symlink to /system/vendor, which is true for
583*8d67ca89SAndroid Build Coastguard Worker // non Treble-ized legacy devices.
584*8d67ca89SAndroid Build Coastguard Worker ns_config->set_search_paths(properties.get_paths(property_name_prefix + ".search.paths", true));
585*8d67ca89SAndroid Build Coastguard Worker
586*8d67ca89SAndroid Build Coastguard Worker // However, for permitted paths, we are not required to resolve the paths
587*8d67ca89SAndroid Build Coastguard Worker // since they are only set for isolated namespaces, which implies the device
588*8d67ca89SAndroid Build Coastguard Worker // is Treble-ized (= /vendor is not a symlink to /system/vendor).
589*8d67ca89SAndroid Build Coastguard Worker // In fact, the resolving is causing an unexpected side effect of selinux
590*8d67ca89SAndroid Build Coastguard Worker // denials on some executables which are not allowed to access some of the
591*8d67ca89SAndroid Build Coastguard Worker // permitted paths.
592*8d67ca89SAndroid Build Coastguard Worker ns_config->set_permitted_paths(properties.get_paths(property_name_prefix + ".permitted.paths", false));
593*8d67ca89SAndroid Build Coastguard Worker }
594*8d67ca89SAndroid Build Coastguard Worker
595*8d67ca89SAndroid Build Coastguard Worker failure_guard.Disable();
596*8d67ca89SAndroid Build Coastguard Worker *config = &g_config;
597*8d67ca89SAndroid Build Coastguard Worker return true;
598*8d67ca89SAndroid Build Coastguard Worker }
599*8d67ca89SAndroid Build Coastguard Worker
get_vndk_version_string(const char delimiter)600*8d67ca89SAndroid Build Coastguard Worker std::string Config::get_vndk_version_string(const char delimiter) {
601*8d67ca89SAndroid Build Coastguard Worker std::string version = android::base::GetProperty("ro.vndk.version", "");
602*8d67ca89SAndroid Build Coastguard Worker if (version != "" && version != "current") {
603*8d67ca89SAndroid Build Coastguard Worker //add the delimiter char in front of the string and return it.
604*8d67ca89SAndroid Build Coastguard Worker return version.insert(0, 1, delimiter);
605*8d67ca89SAndroid Build Coastguard Worker }
606*8d67ca89SAndroid Build Coastguard Worker return "";
607*8d67ca89SAndroid Build Coastguard Worker }
608*8d67ca89SAndroid Build Coastguard Worker
create_namespace_config(const std::string & name)609*8d67ca89SAndroid Build Coastguard Worker NamespaceConfig* Config::create_namespace_config(const std::string& name) {
610*8d67ca89SAndroid Build Coastguard Worker namespace_configs_.push_back(std::unique_ptr<NamespaceConfig>(new NamespaceConfig(name)));
611*8d67ca89SAndroid Build Coastguard Worker NamespaceConfig* ns_config_ptr = namespace_configs_.back().get();
612*8d67ca89SAndroid Build Coastguard Worker namespace_configs_map_[name] = ns_config_ptr;
613*8d67ca89SAndroid Build Coastguard Worker return ns_config_ptr;
614*8d67ca89SAndroid Build Coastguard Worker }
615*8d67ca89SAndroid Build Coastguard Worker
clear()616*8d67ca89SAndroid Build Coastguard Worker void Config::clear() {
617*8d67ca89SAndroid Build Coastguard Worker namespace_configs_.clear();
618*8d67ca89SAndroid Build Coastguard Worker namespace_configs_map_.clear();
619*8d67ca89SAndroid Build Coastguard Worker }
620