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

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