Merge "Use freecon() with getcon()/getfilecon()."
diff --git a/init/README.ueventd.md b/init/README.ueventd.md
index 4363f3c..2a76620 100644
--- a/init/README.ueventd.md
+++ b/init/README.ueventd.md
@@ -13,6 +13,16 @@
uevent_socket_rcvbuf_size 16M
Sets the uevent socket rcvbuf_size to 16 megabytes.
+## Importing configuration files
+--------------------------------
+Ueventd reads /system/etc/ueventd.rc, all other files are imported via the `import` command, which
+takes the format of
+
+ import <path>
+This command parses an ueventd config file, extending the current configuration. If _path_ is a
+directory, each file in the directory is parsed as a config file. It is not recursive, nested
+directories will not be parsed. Imported files are parsed after the current file has been parsed.
+
## /dev
----
Ueventd listens to the kernel uevent sockets and creates/deletes nodes in `/dev` based on the
@@ -32,7 +42,7 @@
The permissions can be modified using a ueventd.rc script and a line that beings with `/dev`. These
lines take the format of
- devname mode uid gid
+ devname mode uid gid [options]
For example
/dev/null 0666 root root
@@ -70,7 +80,7 @@
certain files in `/sys` when matching uevents are generated. This is done using a ueventd.rc script
and a line that begins with `/sys`. These lines take the format of
- nodename attr mode uid gid
+ nodename attr mode uid gid [options]
For example
/sys/devices/system/cpu/cpu* cpufreq/scaling_max_freq 0664 system system
@@ -78,7 +88,15 @@
attribute, `cpufreq/scaling_max_freq`, will have its mode set to `0664`, its user to to `system` and
its group set to `system`.
-Note that `*` matches as a wildcard and can be used anywhere in a path.
+## Path matching
+----------------
+The path for a `/dev` or `/sys` entry can contain a `*` anywhere in the path.
+1. If the only `*` appears at the end of the string or if the _options_ parameter is set to
+`no_fnm_pathname`, ueventd matches the entry by `fnmatch(entry_path, incoming_path, 0)`
+2. Otherwise, ueventd matches the entry by `fnmatch(entry_path, incoming_path, FNM_PATHNAME)`
+
+See the [man page for fnmatch](https://www.man7.org/linux/man-pages/man3/fnmatch.3.html) for more
+details.
## Firmware loading
----------------
diff --git a/init/devices.cpp b/init/devices.cpp
index 5888c06..ce6298a 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -124,8 +124,15 @@
return true;
}
-Permissions::Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t gid)
- : name_(name), perm_(perm), uid_(uid), gid_(gid), prefix_(false), wildcard_(false) {
+Permissions::Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t gid,
+ bool no_fnm_pathname)
+ : name_(name),
+ perm_(perm),
+ uid_(uid),
+ gid_(gid),
+ prefix_(false),
+ wildcard_(false),
+ no_fnm_pathname_(no_fnm_pathname) {
// Set 'prefix_' or 'wildcard_' based on the below cases:
//
// 1) No '*' in 'name' -> Neither are set and Match() checks a given path for strict
@@ -136,7 +143,6 @@
//
// 3) '*' appears elsewhere -> 'wildcard_' is set to true and Match() uses fnmatch()
// with FNM_PATHNAME to compare 'name' to a given path.
-
auto wildcard_position = name_.find('*');
if (wildcard_position != std::string::npos) {
if (wildcard_position == name_.length() - 1) {
@@ -150,7 +156,8 @@
bool Permissions::Match(const std::string& path) const {
if (prefix_) return StartsWith(path, name_);
- if (wildcard_) return fnmatch(name_.c_str(), path.c_str(), FNM_PATHNAME) == 0;
+ if (wildcard_)
+ return fnmatch(name_.c_str(), path.c_str(), no_fnm_pathname_ ? 0 : FNM_PATHNAME) == 0;
return path == name_;
}
@@ -461,9 +468,10 @@
}
void DeviceHandler::HandleUevent(const Uevent& uevent) {
- if (uevent.action == "add" || uevent.action == "change" || uevent.action == "online") {
- FixupSysPermissions(uevent.path, uevent.subsystem);
- }
+ if (uevent.action == "add" || uevent.action == "change" ||
+ uevent.action == "bind" || uevent.action == "online") {
+ FixupSysPermissions(uevent.path, uevent.subsystem);
+ }
// if it's not a /dev device, nothing to do
if (uevent.major < 0 || uevent.minor < 0) return;
diff --git a/init/devices.h b/init/devices.h
index 05d64da..d70d746 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -38,7 +38,7 @@
public:
friend void TestPermissions(const Permissions& expected, const Permissions& test);
- Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t gid);
+ Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t gid, bool no_fnm_pathname);
bool Match(const std::string& path) const;
@@ -56,6 +56,7 @@
gid_t gid_;
bool prefix_;
bool wildcard_;
+ bool no_fnm_pathname_;
};
class SysfsPermissions : public Permissions {
@@ -63,8 +64,8 @@
friend void TestSysfsPermissions(const SysfsPermissions& expected, const SysfsPermissions& test);
SysfsPermissions(const std::string& name, const std::string& attribute, mode_t perm, uid_t uid,
- gid_t gid)
- : Permissions(name, perm, uid, gid), attribute_(attribute) {}
+ gid_t gid, bool no_fnm_pathname)
+ : Permissions(name, perm, uid, gid, no_fnm_pathname), attribute_(attribute) {}
bool MatchWithSubsystem(const std::string& path, const std::string& subsystem) const;
void SetPermissions(const std::string& path) const;
diff --git a/init/devices_test.cpp b/init/devices_test.cpp
index c408bc1..e7bac68 100644
--- a/init/devices_test.cpp
+++ b/init/devices_test.cpp
@@ -221,7 +221,7 @@
TEST(device_handler, DevPermissionsMatchNormal) {
// Basic from ueventd.rc
// /dev/null 0666 root root
- Permissions permissions("/dev/null", 0666, 0, 0);
+ Permissions permissions("/dev/null", 0666, 0, 0, false);
EXPECT_TRUE(permissions.Match("/dev/null"));
EXPECT_FALSE(permissions.Match("/dev/nullsuffix"));
EXPECT_FALSE(permissions.Match("/dev/nul"));
@@ -233,7 +233,7 @@
TEST(device_handler, DevPermissionsMatchPrefix) {
// Prefix from ueventd.rc
// /dev/dri/* 0666 root graphics
- Permissions permissions("/dev/dri/*", 0666, 0, 1000);
+ Permissions permissions("/dev/dri/*", 0666, 0, 1000, false);
EXPECT_TRUE(permissions.Match("/dev/dri/some_dri_device"));
EXPECT_TRUE(permissions.Match("/dev/dri/some_other_dri_device"));
EXPECT_TRUE(permissions.Match("/dev/dri/"));
@@ -246,7 +246,7 @@
TEST(device_handler, DevPermissionsMatchWildcard) {
// Wildcard example
// /dev/device*name 0666 root graphics
- Permissions permissions("/dev/device*name", 0666, 0, 1000);
+ Permissions permissions("/dev/device*name", 0666, 0, 1000, false);
EXPECT_TRUE(permissions.Match("/dev/devicename"));
EXPECT_TRUE(permissions.Match("/dev/device123name"));
EXPECT_TRUE(permissions.Match("/dev/deviceabcname"));
@@ -260,13 +260,31 @@
TEST(device_handler, DevPermissionsMatchWildcardPrefix) {
// Wildcard+Prefix example
// /dev/device*name* 0666 root graphics
- Permissions permissions("/dev/device*name*", 0666, 0, 1000);
+ Permissions permissions("/dev/device*name*", 0666, 0, 1000, false);
EXPECT_TRUE(permissions.Match("/dev/devicename"));
EXPECT_TRUE(permissions.Match("/dev/device123name"));
EXPECT_TRUE(permissions.Match("/dev/deviceabcname"));
EXPECT_TRUE(permissions.Match("/dev/device123namesomething"));
// FNM_PATHNAME doesn't match '/' with *
EXPECT_FALSE(permissions.Match("/dev/device123name/something"));
+ EXPECT_FALSE(permissions.Match("/dev/device/1/2/3name/something"));
+ EXPECT_FALSE(permissions.Match("/dev/deviceame"));
+ EXPECT_EQ(0666U, permissions.perm());
+ EXPECT_EQ(0U, permissions.uid());
+ EXPECT_EQ(1000U, permissions.gid());
+}
+
+TEST(device_handler, DevPermissionsMatchWildcardPrefix_NoFnmPathName) {
+ // Wildcard+Prefix example with no_fnm_pathname
+ // /dev/device*name* 0666 root graphics
+ Permissions permissions("/dev/device*name*", 0666, 0, 1000, true);
+ EXPECT_TRUE(permissions.Match("/dev/devicename"));
+ EXPECT_TRUE(permissions.Match("/dev/device123name"));
+ EXPECT_TRUE(permissions.Match("/dev/deviceabcname"));
+ EXPECT_TRUE(permissions.Match("/dev/device123namesomething"));
+ // With NoFnmPathName, the below matches, unlike DevPermissionsMatchWildcardPrefix.
+ EXPECT_TRUE(permissions.Match("/dev/device123name/something"));
+ EXPECT_TRUE(permissions.Match("/dev/device/1/2/3name/something"));
EXPECT_FALSE(permissions.Match("/dev/deviceame"));
EXPECT_EQ(0666U, permissions.perm());
EXPECT_EQ(0U, permissions.uid());
@@ -275,7 +293,8 @@
TEST(device_handler, SysfsPermissionsMatchWithSubsystemNormal) {
// /sys/devices/virtual/input/input* enable 0660 root input
- SysfsPermissions permissions("/sys/devices/virtual/input/input*", "enable", 0660, 0, 1001);
+ SysfsPermissions permissions("/sys/devices/virtual/input/input*", "enable", 0660, 0, 1001,
+ false);
EXPECT_TRUE(permissions.MatchWithSubsystem("/sys/devices/virtual/input/input0", "input"));
EXPECT_FALSE(permissions.MatchWithSubsystem("/sys/devices/virtual/input/not_input0", "input"));
EXPECT_EQ(0660U, permissions.perm());
@@ -285,7 +304,7 @@
TEST(device_handler, SysfsPermissionsMatchWithSubsystemClass) {
// /sys/class/input/event* enable 0660 root input
- SysfsPermissions permissions("/sys/class/input/event*", "enable", 0660, 0, 1001);
+ SysfsPermissions permissions("/sys/class/input/event*", "enable", 0660, 0, 1001, false);
EXPECT_TRUE(permissions.MatchWithSubsystem(
"/sys/devices/soc.0/f9924000.i2c/i2c-2/2-0020/input/input0/event0", "input"));
EXPECT_FALSE(permissions.MatchWithSubsystem(
@@ -299,7 +318,7 @@
TEST(device_handler, SysfsPermissionsMatchWithSubsystemBus) {
// /sys/bus/i2c/devices/i2c-* enable 0660 root input
- SysfsPermissions permissions("/sys/bus/i2c/devices/i2c-*", "enable", 0660, 0, 1001);
+ SysfsPermissions permissions("/sys/bus/i2c/devices/i2c-*", "enable", 0660, 0, 1001, false);
EXPECT_TRUE(permissions.MatchWithSubsystem("/sys/devices/soc.0/f9967000.i2c/i2c-5", "i2c"));
EXPECT_FALSE(permissions.MatchWithSubsystem("/sys/devices/soc.0/f9967000.i2c/not-i2c", "i2c"));
EXPECT_FALSE(
diff --git a/init/ueventd.cpp b/init/ueventd.cpp
index 54659c5..923d769 100644
--- a/init/ueventd.cpp
+++ b/init/ueventd.cpp
@@ -283,12 +283,7 @@
std::vector<std::unique_ptr<UeventHandler>> uevent_handlers;
- // Keep the current product name base configuration so we remain backwards compatible and
- // allow it to override everything.
- auto hardware = android::base::GetProperty("ro.hardware", "");
-
- auto ueventd_configuration = ParseConfig({"/system/etc/ueventd.rc", "/vendor/ueventd.rc",
- "/odm/ueventd.rc", "/ueventd." + hardware + ".rc"});
+ auto ueventd_configuration = ParseConfig("/system/etc/ueventd.rc");
uevent_handlers.emplace_back(std::make_unique<DeviceHandler>(
std::move(ueventd_configuration.dev_permissions),
diff --git a/init/ueventd_parser.cpp b/init/ueventd_parser.cpp
index 09dce44..2605158 100644
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -21,6 +21,7 @@
#include <android-base/parseint.h>
+#include "import_parser.h"
#include "keyword_map.h"
#include "parser.h"
@@ -33,12 +34,12 @@
std::vector<SysfsPermissions>* out_sysfs_permissions,
std::vector<Permissions>* out_dev_permissions) {
bool is_sysfs = out_sysfs_permissions != nullptr;
- if (is_sysfs && args.size() != 5) {
- return Error() << "/sys/ lines must have 5 entries";
+ if (is_sysfs && !(args.size() == 5 || args.size() == 6)) {
+ return Error() << "/sys/ lines must have 5 or 6 entries";
}
- if (!is_sysfs && args.size() != 4) {
- return Error() << "/dev/ lines must have 4 entries";
+ if (!is_sysfs && !(args.size() == 4 || args.size() == 5)) {
+ return Error() << "/dev/ lines must have 4 or 5 entries";
}
auto it = args.begin();
@@ -69,10 +70,19 @@
}
gid_t gid = grp->gr_gid;
+ bool no_fnm_pathname = false;
+ if (it != args.end()) {
+ std::string& flags = *it++;
+ if (flags != "no_fnm_pathname") {
+ return Error() << "invalid option '" << flags << "', only no_fnm_pathname is supported";
+ }
+ no_fnm_pathname = true;
+ }
+
if (is_sysfs) {
- out_sysfs_permissions->emplace_back(name, sysfs_attribute, perm, uid, gid);
+ out_sysfs_permissions->emplace_back(name, sysfs_attribute, perm, uid, gid, no_fnm_pathname);
} else {
- out_dev_permissions->emplace_back(name, perm, uid, gid);
+ out_dev_permissions->emplace_back(name, perm, uid, gid, no_fnm_pathname);
}
return {};
}
@@ -220,10 +230,11 @@
return {};
}
-UeventdConfiguration ParseConfig(const std::vector<std::string>& configs) {
+UeventdConfiguration ParseConfig(const std::string& config) {
Parser parser;
UeventdConfiguration ueventd_configuration;
+ parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
parser.AddSectionParser("subsystem",
std::make_unique<SubsystemParser>(&ueventd_configuration.subsystems));
@@ -249,9 +260,7 @@
std::bind(ParseEnabledDisabledLine, _1,
&ueventd_configuration.enable_parallel_restorecon));
- for (const auto& config : configs) {
- parser.ParseConfig(config);
- }
+ parser.ParseConfig(config);
return ueventd_configuration;
}
diff --git a/init/ueventd_parser.h b/init/ueventd_parser.h
index eaafa5a..2672626 100644
--- a/init/ueventd_parser.h
+++ b/init/ueventd_parser.h
@@ -36,7 +36,7 @@
bool enable_parallel_restorecon = false;
};
-UeventdConfiguration ParseConfig(const std::vector<std::string>& configs);
+UeventdConfiguration ParseConfig(const std::string& config);
} // namespace init
} // namespace android
diff --git a/init/ueventd_parser_test.cpp b/init/ueventd_parser_test.cpp
index 172ba0b..b604c53 100644
--- a/init/ueventd_parser_test.cpp
+++ b/init/ueventd_parser_test.cpp
@@ -104,21 +104,21 @@
/dev/graphics/* 0660 root graphics
/dev/*/test 0660 root system
-/sys/devices/platform/trusty.* trusty_version 0440 root log
-/sys/devices/virtual/input/input enable 0660 root input
-/sys/devices/virtual/*/input poll_delay 0660 root input
+/sys/devices/platform/trusty.* trusty_version 0440 root log
+/sys/devices/virtual/input/input enable 0660 root input
+/sys/devices/virtual/*/input poll_delay 0660 root input no_fnm_pathname
)";
auto permissions = std::vector<Permissions>{
- {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM},
- {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS},
- {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM},
+ {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM, false},
+ {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS, false},
+ {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM, false},
};
auto sysfs_permissions = std::vector<SysfsPermissions>{
- {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG},
- {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT},
- {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT},
+ {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG, false},
+ {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT, false},
+ {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT, true},
};
TestUeventdFile(ueventd_file, {{}, sysfs_permissions, permissions, {}, {}});
@@ -240,7 +240,7 @@
dirname /dev/graphics
/dev/*/test 0660 root system
-/sys/devices/virtual/*/input poll_delay 0660 root input
+/sys/devices/virtual/*/input poll_delay 0660 root input no_fnm_pathname
firmware_directories /more
external_firmware_handler /devices/path/firmware/firmware001.bin root /vendor/bin/touch.sh
@@ -259,15 +259,15 @@
{"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
auto permissions = std::vector<Permissions>{
- {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM},
- {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS},
- {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM},
+ {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM, false},
+ {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS, false},
+ {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM, false},
};
auto sysfs_permissions = std::vector<SysfsPermissions>{
- {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG},
- {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT},
- {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT},
+ {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG, false},
+ {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT, false},
+ {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT, true},
};
auto firmware_directories = std::vector<std::string>{
@@ -299,6 +299,7 @@
/sys/devices/platform/trusty.* trusty_version badmode root log
/sys/devices/platform/trusty.* trusty_version 0440 baduidbad log
/sys/devices/platform/trusty.* trusty_version 0440 root baduidbad
+/sys/devices/platform/trusty.* trusty_version 0440 root root bad_option
uevent_socket_rcvbuf_size blah
diff --git a/qemu_pipe/OWNERS b/qemu_pipe/OWNERS
index dbc1bf6..d67a329 100644
--- a/qemu_pipe/OWNERS
+++ b/qemu_pipe/OWNERS
@@ -1 +1,3 @@
bohu@google.com
+lfy@google.com
+rkir@google.com
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 1994bdb..42229bd 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -1,3 +1,7 @@
+import /vendor/ueventd.rc
+import /odm/ueventd.rc
+import /ueventd.{ro.hardware}.rc
+
firmware_directories /etc/firmware/ /odm/firmware/ /vendor/firmware/ /firmware/image/
uevent_socket_rcvbuf_size 16M