Matej Habrnal fa1950
From c5cd9d25473e2fea29f7fa609c81ae821e50f118 Mon Sep 17 00:00:00 2001
Matej Habrnal fa1950
From: Jakub Filak <jfilak@redhat.com>
Matej Habrnal fa1950
Date: Thu, 23 Apr 2015 14:46:27 +0200
Matej Habrnal fa1950
Subject: [PATCH] dbus: process only valid sub-directories of the dump location
Matej Habrnal fa1950
Matej Habrnal fa1950
Must have correct rights and must be a direct sub-directory of the dump
Matej Habrnal fa1950
location.
Matej Habrnal fa1950
Matej Habrnal fa1950
This issue was discovered by Florian Weimer of Red Hat Product Security.
Matej Habrnal fa1950
Matej Habrnal fa1950
Related: #1214451
Matej Habrnal fa1950
Matej Habrnal fa1950
Signed-off-by: Jakub Filak <jfilak@redhat.com>
Matej Habrnal fa1950
---
Matej Habrnal fa1950
 src/dbus/abrt-dbus.c  | 46 ++++++++++++++++++++++++++++++++++------------
Matej Habrnal fa1950
 src/lib/problem_api.c |  7 +++++++
Matej Habrnal fa1950
 2 files changed, 41 insertions(+), 12 deletions(-)
Matej Habrnal fa1950
Matej Habrnal fa1950
diff --git a/src/dbus/abrt-dbus.c b/src/dbus/abrt-dbus.c
Matej Habrnal fa1950
index 4eeff41..585fcd7 100644
Matej Habrnal fa1950
--- a/src/dbus/abrt-dbus.c
Matej Habrnal fa1950
+++ b/src/dbus/abrt-dbus.c
Matej Habrnal fa1950
@@ -141,21 +141,20 @@ static uid_t get_caller_uid(GDBusConnection *connection, GDBusMethodInvocation *
Matej Habrnal fa1950
     return caller_uid;
Matej Habrnal fa1950
 }
Matej Habrnal fa1950
 
Matej Habrnal fa1950
-static bool allowed_problem_dir(const char *dir_name)
Matej Habrnal fa1950
+bool allowed_problem_dir(const char *dir_name)
Matej Habrnal fa1950
 {
Matej Habrnal fa1950
-//HACK HACK HACK! Disabled for now until we fix clients (abrt-gui) to not pass /home/user/.cache/abrt/spool
Matej Habrnal fa1950
-#if 0
Matej Habrnal fa1950
-    unsigned len = strlen(g_settings_dump_location);
Matej Habrnal fa1950
-
Matej Habrnal fa1950
-    /* If doesn't start with "g_settings_dump_location[/]"... */
Matej Habrnal fa1950
-    if (strncmp(dir_name, g_settings_dump_location, len) != 0
Matej Habrnal fa1950
-     || (dir_name[len] != '/' && dir_name[len] != '\0')
Matej Habrnal fa1950
-    /* or contains "/." anywhere (-> might contain ".." component) */
Matej Habrnal fa1950
-     || strstr(dir_name + len, "/.")
Matej Habrnal fa1950
-    ) {
Matej Habrnal fa1950
+    if (!dir_is_in_dump_location(dir_name))
Matej Habrnal fa1950
+    {
Matej Habrnal fa1950
+        error_msg("Bad problem directory name '%s', should start with: '%s'", dir_name, g_settings_dump_location);
Matej Habrnal fa1950
         return false;
Matej Habrnal fa1950
     }
Matej Habrnal fa1950
-#endif
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+    if (!dir_has_correct_permissions(dir_name, DD_PERM_DAEMONS))
Matej Habrnal fa1950
+    {
Matej Habrnal fa1950
+        error_msg("Problem directory '%s' has invalid owner, groop or mode", dir_name);
Matej Habrnal fa1950
+        return false;
Matej Habrnal fa1950
+    }
Matej Habrnal fa1950
+
Matej Habrnal fa1950
     return true;
Matej Habrnal fa1950
 }
Matej Habrnal fa1950
 
Matej Habrnal fa1950
@@ -561,6 +560,12 @@ static void handle_method_call(GDBusConnection *connection,
Matej Habrnal fa1950
 
Matej Habrnal fa1950
         g_variant_get(parameters, "(&s)", &problem_id);
Matej Habrnal fa1950
 
Matej Habrnal fa1950
+        if (!allowed_problem_dir(problem_id))
Matej Habrnal fa1950
+        {
Matej Habrnal fa1950
+            return_InvalidProblemDir_error(invocation, problem_id);
Matej Habrnal fa1950
+            return;
Matej Habrnal fa1950
+        }
Matej Habrnal fa1950
+
Matej Habrnal fa1950
         int ddstat = dump_dir_stat_for_uid(problem_id, caller_uid);
Matej Habrnal fa1950
         if ((ddstat & DD_STAT_ACCESSIBLE_BY_UID) == 0 &&
Matej Habrnal fa1950
                 polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
Matej Habrnal fa1950
@@ -624,6 +629,12 @@ static void handle_method_call(GDBusConnection *connection,
Matej Habrnal fa1950
 
Matej Habrnal fa1950
         g_variant_get(parameters, "(&s&s&s)", &problem_id, &element, &value);
Matej Habrnal fa1950
 
Matej Habrnal fa1950
+        if (!allowed_problem_dir(problem_id))
Matej Habrnal fa1950
+        {
Matej Habrnal fa1950
+            return_InvalidProblemDir_error(invocation, problem_id);
Matej Habrnal fa1950
+            return;
Matej Habrnal fa1950
+        }
Matej Habrnal fa1950
+
Matej Habrnal fa1950
         if (element == NULL || element[0] == '\0' || strlen(element) > 64)
Matej Habrnal fa1950
         {
Matej Habrnal fa1950
             log_notice("'%s' is not a valid element name of '%s'", element, problem_id);
Matej Habrnal fa1950
@@ -683,6 +694,12 @@ static void handle_method_call(GDBusConnection *connection,
Matej Habrnal fa1950
 
Matej Habrnal fa1950
         g_variant_get(parameters, "(&s&s)", &problem_id, &element);
Matej Habrnal fa1950
 
Matej Habrnal fa1950
+        if (!allowed_problem_dir(problem_id))
Matej Habrnal fa1950
+        {
Matej Habrnal fa1950
+            return_InvalidProblemDir_error(invocation, problem_id);
Matej Habrnal fa1950
+            return;
Matej Habrnal fa1950
+        }
Matej Habrnal fa1950
+
Matej Habrnal fa1950
         struct dump_dir *dd = open_directory_for_modification_of_element(
Matej Habrnal fa1950
                                     invocation, caller_uid, problem_id, element);
Matej Habrnal fa1950
         if (!dd)
Matej Habrnal fa1950
@@ -715,6 +732,11 @@ static void handle_method_call(GDBusConnection *connection,
Matej Habrnal fa1950
 
Matej Habrnal fa1950
         g_variant_get(parameters, "(&s&s)", &problem_id, &element);
Matej Habrnal fa1950
 
Matej Habrnal fa1950
+        if (!allowed_problem_dir(problem_id))
Matej Habrnal fa1950
+        {
Matej Habrnal fa1950
+            return_InvalidProblemDir_error(invocation, problem_id);
Matej Habrnal fa1950
+            return;
Matej Habrnal fa1950
+        }
Matej Habrnal fa1950
 
Matej Habrnal fa1950
         struct dump_dir *dd = dd_opendir(problem_id, DD_OPEN_READONLY);
Matej Habrnal fa1950
         if (!dd)
Matej Habrnal fa1950
diff --git a/src/lib/problem_api.c b/src/lib/problem_api.c
Matej Habrnal fa1950
index 07707db..86222cf 100644
Matej Habrnal fa1950
--- a/src/lib/problem_api.c
Matej Habrnal fa1950
+++ b/src/lib/problem_api.c
Matej Habrnal fa1950
@@ -76,6 +76,13 @@ int for_each_problem_in_dir(const char *path,
Matej Habrnal fa1950
 
Matej Habrnal fa1950
 static int add_dirname_to_GList(struct dump_dir *dd, void *arg)
Matej Habrnal fa1950
 {
Matej Habrnal fa1950
+    if (!dir_has_correct_permissions(dd->dd_dirname, DD_PERM_DAEMONS))
Matej Habrnal fa1950
+    {
Matej Habrnal fa1950
+        log("Ignoring '%s': invalid owner, group or mode", dd->dd_dirname);
Matej Habrnal fa1950
+        /*Do not break*/
Matej Habrnal fa1950
+        return 0;
Matej Habrnal fa1950
+    }
Matej Habrnal fa1950
+
Matej Habrnal fa1950
     GList **list = arg;
Matej Habrnal fa1950
     *list = g_list_prepend(*list, xstrdup(dd->dd_dirname));
Matej Habrnal fa1950
     return 0;
Matej Habrnal fa1950
-- 
Matej Habrnal fa1950
2.1.0
Matej Habrnal fa1950