chiark / gitweb /
dbus: add some more safety checks before accepting data from bus clients
authorLennart Poettering <lennart@poettering.net>
Wed, 3 Oct 2012 17:29:20 +0000 (13:29 -0400)
committerLennart Poettering <lennart@poettering.net>
Wed, 3 Oct 2012 17:29:20 +0000 (13:29 -0400)
src/hostname/hostnamed.c
src/journal/journald-native.c
src/locale/localed.c
src/shared/util.c
src/shared/util.h

index 8f9d5a04f5b73393930ac02c0eac34ccd2192bb7..cd3ef491ac3ec4fb9efae6d3ab78c7904de3abd0 100644 (file)
@@ -451,6 +451,14 @@ static DBusHandlerResult hostname_message_handler(
                         } else {
                                 char *h;
 
+                                /* The icon name might ultimately be
+                                 * used as file name, so better be
+                                 * safe than sorry */
+                                if (k == PROP_ICON_NAME && !filename_is_safe(name))
+                                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+                                if (k == PROP_PRETTY_HOSTNAME && !string_is_safe(name))
+                                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
                                 h = strdup(name);
                                 if (!h)
                                         goto oom;
index 12fb980dd6c5312df7c8875332ae3d05f0003c69..de8d6998cfdc0c7a35d381041d7d308be72ef802 100644 (file)
@@ -314,7 +314,7 @@ void server_process_native_file(
                         return;
                 }
 
-                if (strchr(e, '/')) {
+                if (!filename_is_safe(e)) {
                         log_error("Received file in subdirectory of allowed directories. Refusing.");
                         return;
                 }
index a2d381406c6da0ac3beb9809e154b4da7e9ae7ca..04268a19821f1559ea4cc4665ffa596e890aff91 100644 (file)
@@ -1039,7 +1039,9 @@ static DBusHandlerResult locale_message_handler(
                                 size_t k;
 
                                 k = strlen(names[p]);
-                                if (startswith(*i, names[p]) && (*i)[k] == '=') {
+                                if (startswith(*i, names[p]) &&
+                                    (*i)[k] == '=' &&
+                                    string_is_safe((*i) + k + 1)) {
                                         valid = true;
                                         passed[p] = true;
 
@@ -1150,6 +1152,10 @@ static DBusHandlerResult locale_message_handler(
                 if (!streq_ptr(keymap, state.vc_keymap) ||
                     !streq_ptr(keymap_toggle, state.vc_keymap_toggle)) {
 
+                        if ((keymap && (!filename_is_safe(keymap) || !string_is_safe(keymap))) ||
+                            (keymap_toggle && (!filename_is_safe(keymap_toggle) || !string_is_safe(keymap_toggle))))
+                                return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
                         r = verify_polkit(connection, message, "org.freedesktop.locale1.set-keyboard", interactive, NULL, &error);
                         if (r < 0)
                                 return bus_send_error_reply(connection, message, &error, r);
@@ -1220,6 +1226,12 @@ static DBusHandlerResult locale_message_handler(
                     !streq_ptr(variant, state.x11_variant) ||
                     !streq_ptr(options, state.x11_options)) {
 
+                        if ((layout && !string_is_safe(layout)) ||
+                            (model && !string_is_safe(model)) ||
+                            (variant && !string_is_safe(variant)) ||
+                            (options && !string_is_safe(options)))
+                                return bus_send_error_reply(connection, message, NULL, -EINVAL);
+
                         r = verify_polkit(connection, message, "org.freedesktop.locale1.set-keyboard", interactive, NULL, &error);
                         if (r < 0)
                                 return bus_send_error_reply(connection, message, &error, r);
index d2ca3fc783a9c7f8d7b6d90ec569207a3118da23..64d6e62a5323b573d87c3f32f2ee76618212be59 100644 (file)
@@ -56,6 +56,7 @@
 #include <sys/mman.h>
 #include <sys/vfs.h>
 #include <linux/magic.h>
+#include <limits.h>
 
 #include "macro.h"
 #include "util.h"
@@ -5851,3 +5852,39 @@ void closedirp(DIR **d) {
 void umaskp(mode_t *u) {
         umask(*u);
 }
+
+bool filename_is_safe(const char *p) {
+
+        if (isempty(p))
+                return false;
+
+        if (strchr(p, '/'))
+                return false;
+
+        if (streq(p, "."))
+                return false;
+
+        if (streq(p, ".."))
+                return false;
+
+        if (strlen(p) > FILENAME_MAX)
+                return false;
+
+        return true;
+}
+
+bool string_is_safe(const char *p) {
+        const char *t;
+
+        assert(p);
+
+        for (t = p; *t; t++) {
+                if (*p < ' ')
+                        return false;
+
+                if (strchr("\\\"\'", *p))
+                        return false;
+        }
+
+        return true;
+}
index 61b88a8b2e6ad0279dea5ecef46609b72115605a..cbded086177c34704d972f0399507359f1196504 100644 (file)
@@ -558,3 +558,6 @@ _malloc_ static inline void *memdup_multiply(const void *p, size_t a, size_t b)
 
         return memdup(p, a * b);
 }
+
+bool filename_is_safe(const char *p);
+bool string_is_safe(const char *p);