Blob Blame History Raw
From e76a8655152129de09bd9521ade8158bb07cc8fe Mon Sep 17 00:00:00 2001
From: Jakub Filak <jfilak@redhat.com>
Date: Wed, 15 Apr 2015 17:41:49 +0200
Subject: [LIBREPORT PATCH] dump_dir: allow hooks to create dump directory
 without parents

With a centralized model of handling problems like ABRT, there is a need
to ensure that every dump directory is a descendant of some central
directory (database). This commit together with other security commits
makes code of the tools creating the dump directories in the central
directory more robust by ensuring that no tool accidentally creates the
central directory and all tools creates exactly one directory.

Related: #1211835

Signed-off-by: Jakub Filak <jfilak@redhat.com>
---
 src/include/dump_dir.h |  4 +++-
 src/lib/dump_dir.c     | 12 +++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/include/dump_dir.h b/src/include/dump_dir.h
index 71cf66f..8f672d3 100644
--- a/src/include/dump_dir.h
+++ b/src/include/dump_dir.h
@@ -43,6 +43,8 @@ enum {
     DD_OPEN_READONLY = (1 << 3),
     DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE = (1 << 4),
     DD_DONT_WAIT_FOR_LOCK = (1 << 5),
+    /* Create the new dump directory with parent directories (mkdir -p)*/
+    DD_CREATE_PARENTS = (1 << 6),
 };
 
 struct dump_dir {
@@ -60,7 +62,7 @@ struct dump_dir {
 void dd_close(struct dump_dir *dd);
 
 struct dump_dir *dd_opendir(const char *dir, int flags);
-struct dump_dir *dd_create_skeleton(const char *dir, uid_t uid, mode_t mode);
+struct dump_dir *dd_create_skeleton(const char *dir, uid_t uid, mode_t mode, int flags);
 int dd_reset_ownership(struct dump_dir *dd);
 /* Pass uid = (uid_t)-1L to disable chown'ing of newly created files
  * (IOW: if you aren't running under root):
diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c
index fabad0b..2a65100 100644
--- a/src/lib/dump_dir.c
+++ b/src/lib/dump_dir.c
@@ -514,7 +514,7 @@ struct dump_dir *dd_opendir(const char *dir, int flags)
  *     this runs under 0:0
  *     - clients: setroubleshootd, abrt python
  */
-struct dump_dir *dd_create_skeleton(const char *dir, uid_t uid, mode_t mode)
+struct dump_dir *dd_create_skeleton(const char *dir, uid_t uid, mode_t mode, int flags)
 {
     /* a little trick to copy read bits from file mode to exec bit of dir mode*/
     mode_t dir_mode = mode | ((mode & 0444) >> 2);
@@ -547,7 +547,13 @@ struct dump_dir *dd_create_skeleton(const char *dir, uid_t uid, mode_t mode)
      * the user to replace any file in the directory, changing security-sensitive data
      * (e.g. "uid", "analyzer", "executable")
      */
-    if (g_mkdir_with_parents(dd->dd_dirname, dir_mode) != 0)
+    int r;
+    if ((flags & DD_CREATE_PARENTS))
+        r = g_mkdir_with_parents(dd->dd_dirname, dir_mode);
+    else
+        r = mkdir(dd->dd_dirname, dir_mode);
+
+    if (r != 0)
     {
         perror_msg("Can't create directory '%s'", dir);
         dd_close(dd);
@@ -627,7 +633,7 @@ int dd_reset_ownership(struct dump_dir *dd)
  */
 struct dump_dir *dd_create(const char *dir, uid_t uid, mode_t mode)
 {
-    struct dump_dir *dd = dd_create_skeleton(dir, uid, mode);
+    struct dump_dir *dd = dd_create_skeleton(dir, uid, mode, DD_CREATE_PARENTS);
     if (dd == NULL)
         return NULL;
 
-- 
1.8.3.1