Merge "init: Ignore "ro." restrictions when reading prop files"
This commit is contained in:
commit
86f38d56b8
|
@ -39,6 +39,7 @@
|
|||
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
|
||||
#include <sys/_system_properties.h>
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <queue>
|
||||
#include <vector>
|
||||
|
@ -442,8 +443,8 @@ bool CheckControlPropertyPerms(const std::string& name, const std::string& value
|
|||
}
|
||||
|
||||
// This returns one of the enum of PROP_SUCCESS or PROP_ERROR*.
|
||||
uint32_t HandlePropertySet(const std::string& name, const std::string& value,
|
||||
const std::string& source_context, const ucred& cr, std::string* error) {
|
||||
uint32_t CheckPermissions(const std::string& name, const std::string& value,
|
||||
const std::string& source_context, const ucred& cr, std::string* error) {
|
||||
if (!IsLegalPropertyName(name)) {
|
||||
*error = "Illegal property name";
|
||||
return PROP_ERROR_INVALID_NAME;
|
||||
|
@ -456,7 +457,6 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value,
|
|||
return PROP_ERROR_HANDLE_CONTROL_MESSAGE;
|
||||
}
|
||||
|
||||
HandleControlMessage(name.c_str() + 4, value, cr.pid);
|
||||
return PROP_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -475,6 +475,21 @@ uint32_t HandlePropertySet(const std::string& name, const std::string& value,
|
|||
return PROP_ERROR_INVALID_VALUE;
|
||||
}
|
||||
|
||||
return PROP_SUCCESS;
|
||||
}
|
||||
|
||||
// This returns one of the enum of PROP_SUCCESS or PROP_ERROR*.
|
||||
uint32_t HandlePropertySet(const std::string& name, const std::string& value,
|
||||
const std::string& source_context, const ucred& cr, std::string* error) {
|
||||
if (auto ret = CheckPermissions(name, value, source_context, cr, error); ret != PROP_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (StartsWith(name, "ctl.")) {
|
||||
HandleControlMessage(name.c_str() + 4, value, cr.pid);
|
||||
return PROP_SUCCESS;
|
||||
}
|
||||
|
||||
// sys.powerctl is a special property that is used to make the device reboot. We want to log
|
||||
// any process that sets this property to be able to accurately blame the cause of a shutdown.
|
||||
if (name == "sys.powerctl") {
|
||||
|
@ -579,13 +594,15 @@ static void handle_property_set_fd() {
|
|||
}
|
||||
}
|
||||
|
||||
static bool load_properties_from_file(const char *, const char *);
|
||||
static bool load_properties_from_file(const char*, const char*,
|
||||
std::map<std::string, std::string>*);
|
||||
|
||||
/*
|
||||
* Filter is used to decide which properties to load: NULL loads all keys,
|
||||
* "ro.foo.*" is a prefix match, and "ro.foo.bar" is an exact match.
|
||||
*/
|
||||
static void LoadProperties(char* data, const char* filter, const char* filename) {
|
||||
static void LoadProperties(char* data, const char* filter, const char* filename,
|
||||
std::map<std::string, std::string>* properties) {
|
||||
char *key, *value, *eol, *sol, *tmp, *fn;
|
||||
size_t flen = 0;
|
||||
|
||||
|
@ -624,7 +641,7 @@ static void LoadProperties(char* data, const char* filter, const char* filename)
|
|||
while (isspace(*key)) key++;
|
||||
}
|
||||
|
||||
load_properties_from_file(fn, key);
|
||||
load_properties_from_file(fn, key, properties);
|
||||
|
||||
} else {
|
||||
value = strchr(key, '=');
|
||||
|
@ -651,12 +668,19 @@ static void LoadProperties(char* data, const char* filter, const char* filename)
|
|||
continue;
|
||||
}
|
||||
|
||||
uint32_t result = 0;
|
||||
ucred cr = {.pid = 1, .uid = 0, .gid = 0};
|
||||
std::string error;
|
||||
result = HandlePropertySet(key, value, context, cr, &error);
|
||||
if (result != PROP_SUCCESS) {
|
||||
LOG(ERROR) << "Unable to set property '" << key << "' to '" << value
|
||||
if (CheckPermissions(key, value, context, cr, &error) == PROP_SUCCESS) {
|
||||
auto it = properties->find(key);
|
||||
if (it == properties->end()) {
|
||||
(*properties)[key] = value;
|
||||
} else if (it->second != value) {
|
||||
LOG(WARNING) << "Overriding previous 'ro.' property '" << key << "':'"
|
||||
<< it->second << "' with new value '" << value << "'";
|
||||
it->second = value;
|
||||
}
|
||||
} else {
|
||||
LOG(ERROR) << "Do not have permissions to set '" << key << "' to '" << value
|
||||
<< "' in property file '" << filename << "': " << error;
|
||||
}
|
||||
}
|
||||
|
@ -665,7 +689,8 @@ static void LoadProperties(char* data, const char* filter, const char* filename)
|
|||
|
||||
// Filter is used to decide which properties to load: NULL loads all keys,
|
||||
// "ro.foo.*" is a prefix match, and "ro.foo.bar" is an exact match.
|
||||
static bool load_properties_from_file(const char* filename, const char* filter) {
|
||||
static bool load_properties_from_file(const char* filename, const char* filter,
|
||||
std::map<std::string, std::string>* properties) {
|
||||
Timer t;
|
||||
auto file_contents = ReadFile(filename);
|
||||
if (!file_contents) {
|
||||
|
@ -675,7 +700,7 @@ static bool load_properties_from_file(const char* filename, const char* filter)
|
|||
}
|
||||
file_contents->push_back('\n');
|
||||
|
||||
LoadProperties(file_contents->data(), filter, filename);
|
||||
LoadProperties(file_contents->data(), filter, filename, properties);
|
||||
LOG(VERBOSE) << "(Loading properties from " << filename << " took " << t << ".)";
|
||||
return true;
|
||||
}
|
||||
|
@ -698,7 +723,15 @@ static void update_sys_usb_config() {
|
|||
|
||||
static void load_override_properties() {
|
||||
if (ALLOW_LOCAL_PROP_OVERRIDE) {
|
||||
load_properties_from_file("/data/local.prop", NULL);
|
||||
std::map<std::string, std::string> properties;
|
||||
load_properties_from_file("/data/local.prop", nullptr, &properties);
|
||||
for (const auto& [name, value] : properties) {
|
||||
std::string error;
|
||||
if (PropertySet(name, value, &error) != PROP_SUCCESS) {
|
||||
LOG(ERROR) << "Could not set '" << name << "' to '" << value
|
||||
<< "' in /data/local.prop: " << error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -835,24 +868,33 @@ static void property_derive_build_fingerprint() {
|
|||
|
||||
void property_load_boot_defaults() {
|
||||
// TODO(b/117892318): merge prop.default and build.prop files into one
|
||||
// TODO(b/122864654): read the prop files from all partitions and then
|
||||
// resolve the duplication by their origin so that RO and non-RO properties
|
||||
// have a consistent overriding order.
|
||||
if (!load_properties_from_file("/system/etc/prop.default", NULL)) {
|
||||
// We read the properties and their values into a map, in order to always allow properties
|
||||
// loaded in the later property files to override the properties in loaded in the earlier
|
||||
// property files, regardless of if they are "ro." properties or not.
|
||||
std::map<std::string, std::string> properties;
|
||||
if (!load_properties_from_file("/system/etc/prop.default", nullptr, &properties)) {
|
||||
// Try recovery path
|
||||
if (!load_properties_from_file("/prop.default", NULL)) {
|
||||
if (!load_properties_from_file("/prop.default", nullptr, &properties)) {
|
||||
// Try legacy path
|
||||
load_properties_from_file("/default.prop", NULL);
|
||||
load_properties_from_file("/default.prop", nullptr, &properties);
|
||||
}
|
||||
}
|
||||
load_properties_from_file("/system/build.prop", nullptr, &properties);
|
||||
load_properties_from_file("/vendor/default.prop", nullptr, &properties);
|
||||
load_properties_from_file("/vendor/build.prop", nullptr, &properties);
|
||||
load_properties_from_file("/odm/default.prop", nullptr, &properties);
|
||||
load_properties_from_file("/odm/build.prop", nullptr, &properties);
|
||||
load_properties_from_file("/product/build.prop", nullptr, &properties);
|
||||
load_properties_from_file("/product_services/build.prop", nullptr, &properties);
|
||||
load_properties_from_file("/factory/factory.prop", "ro.*", &properties);
|
||||
|
||||
for (const auto& [name, value] : properties) {
|
||||
std::string error;
|
||||
if (PropertySet(name, value, &error) != PROP_SUCCESS) {
|
||||
LOG(ERROR) << "Could not set '" << name << "' to '" << value
|
||||
<< "' while loading .prop files" << error;
|
||||
}
|
||||
}
|
||||
load_properties_from_file("/product/build.prop", NULL);
|
||||
load_properties_from_file("/product_services/build.prop", NULL);
|
||||
load_properties_from_file("/odm/default.prop", NULL);
|
||||
load_properties_from_file("/vendor/default.prop", NULL);
|
||||
load_properties_from_file("/system/build.prop", NULL);
|
||||
load_properties_from_file("/odm/build.prop", NULL);
|
||||
load_properties_from_file("/vendor/build.prop", NULL);
|
||||
load_properties_from_file("/factory/factory.prop", "ro.*");
|
||||
|
||||
property_initialize_ro_product_props();
|
||||
property_derive_build_fingerprint();
|
||||
|
|
Loading…
Reference in New Issue