Blame 0178-a-a-i-d-to-abrt-cache-make-own-random-temporary-dire.patch

69165ba
From e721bc775d9270ac8d9d8daf2fe3f83bffe5d761 Mon Sep 17 00:00:00 2001
69165ba
From: Jakub Filak <jfilak@redhat.com>
69165ba
Date: Wed, 30 Sep 2015 11:50:18 +0200
69165ba
Subject: [PATCH] a-a-i-d-to-abrt-cache: make own random temporary directory
69165ba
69165ba
The set-user-ID wrapper must use own new temporary directory in order to
69165ba
avoid security issues with unpacking specially crafted debuginfo
69165ba
packages that might be used to create files or symlinks anywhere on the
69165ba
file system as the abrt user.
69165ba
69165ba
Withot the forking code the temporary directory would remain on the
69165ba
filesystem in the case where all debuginfo data are already available.
69165ba
This is caused by the fact that the underlying libreport functionality
69165ba
accepts path to a desired temporary directory and creates it only if
69165ba
necessary. Otherwise, the directory is not touched at all.
69165ba
69165ba
This commit addresses CVE-2015-5273
69165ba
Related: #1262252
69165ba
69165ba
Signed-off-by: Jakub Filak <jfilak@redhat.com>
69165ba
---
69165ba
 src/plugins/Makefile.am                            |  1 +
69165ba
 .../abrt-action-install-debuginfo-to-abrt-cache.c  | 41 +++++++++++++++++++---
69165ba
 2 files changed, 38 insertions(+), 4 deletions(-)
69165ba
69165ba
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
69165ba
index 326bb6e..6dde4b7 100644
69165ba
--- a/src/plugins/Makefile.am
69165ba
+++ b/src/plugins/Makefile.am
69165ba
@@ -261,6 +261,7 @@ abrt_action_install_debuginfo_to_abrt_cache_CPPFLAGS = \
69165ba
     -D_GNU_SOURCE \
69165ba
     -DBIN_DIR=\"$(bindir)\" \
69165ba
     -DSBIN_DIR=\"$(sbindir)\" \
69165ba
+    -DLARGE_DATA_TMP_DIR=\"$(LARGE_DATA_TMP_DIR)\" \
69165ba
     $(LIBREPORT_CFLAGS) \
69165ba
     -Wall -Wwrite-strings \
69165ba
     -fPIE
69165ba
diff --git a/src/plugins/abrt-action-install-debuginfo-to-abrt-cache.c b/src/plugins/abrt-action-install-debuginfo-to-abrt-cache.c
69165ba
index 81b1486..52d00de 100644
69165ba
--- a/src/plugins/abrt-action-install-debuginfo-to-abrt-cache.c
69165ba
+++ b/src/plugins/abrt-action-install-debuginfo-to-abrt-cache.c
69165ba
@@ -108,8 +108,14 @@ int main(int argc, char **argv)
69165ba
         build_ids_self_fd = xasprintf("/proc/self/fd/%d", build_ids_fd);
69165ba
     }
69165ba
 
69165ba
-    /* name, -v, --ids, -, -y, -e, EXACT, -r, REPO, --, NULL */
69165ba
-    const char *args[11];
69165ba
+    char tmp_directory[] = LARGE_DATA_TMP_DIR"/abrt-tmp-debuginfo.XXXXXX";
69165ba
+    if (mkdtemp(tmp_directory) == NULL)
69165ba
+        perror_msg_and_die("Failed to create working directory");
69165ba
+
69165ba
+    log_info("Created working directory: %s", tmp_directory);
69165ba
+
69165ba
+    /* name, -v, --ids, -, -y, -e, EXACT, -r, REPO, -t, PATH, --, NULL */
69165ba
+    const char *args[13];
69165ba
     {
69165ba
         const char *verbs[] = { "", "-v", "-vv", "-vvv" };
69165ba
         unsigned i = 0;
69165ba
@@ -130,6 +136,8 @@ int main(int argc, char **argv)
69165ba
             args[i++] = "--repo";
69165ba
             args[i++] = repo;
69165ba
         }
69165ba
+        args[i++] = "--tmpdir";
69165ba
+        args[i++] = tmp_directory;
69165ba
         args[i++] = "--";
69165ba
         args[i] = NULL;
69165ba
     }
69165ba
@@ -204,6 +212,31 @@ int main(int argc, char **argv)
69165ba
         umask(0022);
69165ba
     }
69165ba
 
69165ba
-    execvp(EXECUTABLE, (char **)args);
69165ba
-    error_msg_and_die("Can't execute %s", EXECUTABLE);
69165ba
+    pid_t pid = fork();
69165ba
+    if (pid < 0)
69165ba
+        perror_msg_and_die("fork");
69165ba
+
69165ba
+    if (pid == 0)
69165ba
+    {
69165ba
+        execvp(EXECUTABLE, (char **)args);
69165ba
+        error_msg_and_die("Can't execute %s", EXECUTABLE);
69165ba
+    }
69165ba
+
69165ba
+    int status;
69165ba
+    if (safe_waitpid(pid, &status, 0) < 0)
69165ba
+        perror_msg_and_die("waitpid");
69165ba
+
69165ba
+    if (rmdir(tmp_directory) >= 0)
69165ba
+        log_info("Removed working directory: %s", tmp_directory);
69165ba
+    else if (errno != ENOENT)
69165ba
+        perror_msg("Failed to remove working directory");
69165ba
+
69165ba
+    /* Normal execution should exit here. */
69165ba
+    if (WIFEXITED(status))
69165ba
+        return WEXITSTATUS(status);
69165ba
+
69165ba
+    if (WIFSIGNALED(status))
69165ba
+        error_msg_and_die("Child terminated with signal %d", WTERMSIG(status));
69165ba
+
69165ba
+    error_msg_and_die("Child exit failed");
69165ba
 }
69165ba
-- 
69165ba
1.8.3.1
69165ba