]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: rework how we validate DeviceAllow= settings
authorLennart Poettering <lennart@poettering.net>
Mon, 11 Jun 2018 10:22:58 +0000 (12:22 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 11 Jun 2018 16:01:06 +0000 (18:01 +0200)
Let's make sure we don't validate "char-*" and "block-*" expressions as
paths.

src/basic/path-util.c
src/basic/path-util.h
src/core/dbus-cgroup.c
src/core/load-fragment.c

index f36301ccf5ae3c719f5dd6dfc03c01d47c8c929f..062b95182cfdd3668eee9e6b4537176df7e59c87 100644 (file)
@@ -893,10 +893,31 @@ bool is_device_path(const char *path) {
                path_startswith(path, "/sys/");
 }
 
-bool is_deviceallow_pattern(const char *path) {
-        return path_startswith(path, "/dev/") ||
-               startswith(path, "block-") ||
-               startswith(path, "char-");
+bool valid_device_node_path(const char *path) {
+
+        /* Some superficial checks whether the specified path is a valid device node path, all without looking at the
+         * actual device node. */
+
+        if (!PATH_STARTSWITH_SET(path, "/dev/", "/run/systemd/inaccessible/"))
+                return false;
+
+        if (endswith(path, "/")) /* can't be a device node if it ends in a slash */
+                return false;
+
+        return path_is_normalized(path);
+}
+
+bool valid_device_allow_pattern(const char *path) {
+        assert(path);
+
+        /* Like valid_device_node_path(), but also allows full-subsystem expressions, like DeviceAllow= and DeviceDeny=
+         * accept it */
+
+        if (startswith(path, "block-") ||
+            startswith(path, "char-"))
+                return true;
+
+        return valid_device_node_path(path);
 }
 
 int systemd_installation_has_version(const char *root, unsigned minimal_version) {
index d8a923d3cd7511d26032f1a8994322673f21c932..486046f861ae8f77cb044d48df4fbd1fa98a2738 100644 (file)
@@ -147,7 +147,9 @@ char *file_in_same_dir(const char *path, const char *filename);
 bool hidden_or_backup_file(const char *filename) _pure_;
 
 bool is_device_path(const char *path);
-bool is_deviceallow_pattern(const char *path);
+
+bool valid_device_node_path(const char *path);
+bool valid_device_allow_pattern(const char *path);
 
 int systemd_installation_has_version(const char *root, unsigned minimal_version);
 
index 194b5379dc9f11446ce3bde8d87d4317a0c59c4e..4eb72269792c908b5df3d82a174b15f5251c840b 100644 (file)
@@ -1059,15 +1059,12 @@ int bus_cgroup_set_property(
 
                 while ((r = sd_bus_message_read(message, "(ss)", &path, &rwm)) > 0) {
 
-                        if ((!is_deviceallow_pattern(path) &&
-                             !path_startswith(path, "/run/systemd/inaccessible/")) ||
-                            strpbrk(path, WHITESPACE))
-                            return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires device node");
+                        if (!valid_device_allow_pattern(path) || strpbrk(path, WHITESPACE))
+                                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires device node or pattern");
 
                         if (isempty(rwm))
                                 rwm = "rwm";
-
-                        if (!in_charset(rwm, "rwm"))
+                        else if (!in_charset(rwm, "rwm"))
                                 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "DeviceAllow= requires combination of rwm flags");
 
                         if (!UNIT_WRITE_FLAGS_NOOP(flags)) {
index 2d8525c4bd10986aa09f3c3eed260645db8120c8..935f6be8077859b30d375a92868781bb125f50b7 100644 (file)
@@ -3234,14 +3234,16 @@ int config_parse_device_allow(
                 return 0;
         }
 
-        r = path_simplify_and_warn(resolved, 0, unit, filename, line, lvalue);
-        if (r < 0)
-                return 0;
+        if (!startswith(resolved, "block-") && !startswith(resolved, "char-")) {
 
-        if (!is_deviceallow_pattern(resolved) &&
-            !path_startswith(resolved, "/run/systemd/inaccessible/")) {
-                log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
-                return 0;
+                r = path_simplify_and_warn(resolved, 0, unit, filename, line, lvalue);
+                if (r < 0)
+                        return 0;
+
+                if (!valid_device_node_path(resolved)) {
+                        log_syntax(unit, LOG_ERR, filename, line, 0, "Invalid device node path '%s', ignoring.", resolved);
+                        return 0;
+                }
         }
 
         if (!isempty(p) && !in_charset(p, "rwm")) {