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

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