Matej Habrnal fa1950
From f51412944254a5abcbd1458e0b4bfa9d876e2fa9 Mon Sep 17 00:00:00 2001
Matej Habrnal fa1950
From: Jakub Filak <jfilak@redhat.com>
Matej Habrnal fa1950
Date: Mon, 4 May 2015 13:23:43 +0200
Matej Habrnal fa1950
Subject: [PATCH] ccpp: revert the UID/GID changes if user core fails
Matej Habrnal fa1950
Matej Habrnal fa1950
Thanks Florian Weimer <fweimer@redhat.com>
Matej Habrnal fa1950
Matej Habrnal fa1950
Signed-off-by: Jakub Filak <jfilak@redhat.com>
Matej Habrnal fa1950
---
Matej Habrnal fa1950
 src/hooks/abrt-hook-ccpp.c | 58 ++++++++++++++++++++++++++++------------------
Matej Habrnal fa1950
 1 file changed, 36 insertions(+), 22 deletions(-)
Matej Habrnal fa1950
Matej Habrnal fa1950
diff --git a/src/hooks/abrt-hook-ccpp.c b/src/hooks/abrt-hook-ccpp.c
Matej Habrnal fa1950
index c4ad8d1..0448216 100644
Matej Habrnal fa1950
--- a/src/hooks/abrt-hook-ccpp.c
Matej Habrnal fa1950
+++ b/src/hooks/abrt-hook-ccpp.c
Matej Habrnal fa1950
@@ -226,9 +226,6 @@ static int open_user_core(uid_t uid, uid_t fsuid, gid_t fsgid, pid_t pid, char *
Matej Habrnal fa1950
         return -1;
Matej Habrnal fa1950
     }
Matej Habrnal fa1950
 
Matej Habrnal fa1950
-    xsetegid(fsgid);
Matej Habrnal fa1950
-    xseteuid(fsuid);
Matej Habrnal fa1950
-
Matej Habrnal fa1950
     if (strcmp(core_basename, "core") == 0)
Matej Habrnal fa1950
     {
Matej Habrnal fa1950
         /* Mimic "core.PID" if requested */
Matej Habrnal fa1950
@@ -321,36 +318,53 @@ static int open_user_core(uid_t uid, uid_t fsuid, gid_t fsgid, pid_t pid, char *
Matej Habrnal fa1950
      * and the description of the /proc/sys/fs/suid_dumpable file in proc(5).)
Matej Habrnal fa1950
      */
Matej Habrnal fa1950
 
Matej Habrnal fa1950
-    /* Set SELinux context like kernel when creating core dump file */
Matej Habrnal fa1950
-    if (newcon != NULL && setfscreatecon_raw(newcon) < 0)
Matej Habrnal fa1950
-    {
Matej Habrnal fa1950
-        perror_msg("setfscreatecon_raw(%s)", newcon);
Matej Habrnal fa1950
-        return -1;
Matej Habrnal fa1950
-    }
Matej Habrnal fa1950
+    int user_core_fd = -1;
Matej Habrnal fa1950
+    int selinux_fail = 1;
Matej Habrnal fa1950
 
Matej Habrnal fa1950
-    struct stat sb;
Matej Habrnal fa1950
-    errno = 0;
Matej Habrnal fa1950
-    /* Do not O_TRUNC: if later checks fail, we do not want to have file already modified here */
Matej Habrnal fa1950
-    int user_core_fd = openat(dirfd(proc_cwd), core_basename, O_WRONLY | O_CREAT | O_NOFOLLOW | g_user_core_flags, 0600); /* kernel makes 0600 too */
Matej Habrnal fa1950
+    /*
Matej Habrnal fa1950
+     * These calls must be reverted as soon as possible.
Matej Habrnal fa1950
+     */
Matej Habrnal fa1950
+    xsetegid(fsgid);
Matej Habrnal fa1950
+    xseteuid(fsuid);
Matej Habrnal fa1950
 
Matej Habrnal fa1950
-    if (newcon != NULL && setfscreatecon_raw(NULL) < 0)
Matej Habrnal fa1950
+    /* Set SELinux context like kernel when creating core dump file.
Matej Habrnal fa1950
+     * This condition is TRUE if */
Matej Habrnal fa1950
+    if (/* SELinux is disabled  */ newcon == NULL
Matej Habrnal fa1950
+     || /* or the call succeeds */ setfscreatecon_raw(newcon) >= 0)
Matej Habrnal fa1950
     {
Matej Habrnal fa1950
-        error_msg("setfscreatecon_raw(NULL)");
Matej Habrnal fa1950
-        goto user_core_fail;
Matej Habrnal fa1950
+        /* Do not O_TRUNC: if later checks fail, we do not want to have file already modified here */
Matej Habrnal fa1950
+        user_core_fd = openat(dirfd(proc_cwd), core_basename, O_WRONLY | O_CREAT | O_NOFOLLOW | g_user_core_flags, 0600); /* kernel makes 0600 too */
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        /* Do the error check here and print the error message in order to
Matej Habrnal fa1950
+         * avoid interference in 'errno' usage caused by SELinux functions */
Matej Habrnal fa1950
+        if (user_core_fd < 0)
Matej Habrnal fa1950
+            perror_msg("Can't open '%s' at '%s'", core_basename, user_pwd);
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+        /* Fail if SELinux is enabled and the call fails */
Matej Habrnal fa1950
+        if (newcon != NULL && setfscreatecon_raw(NULL) < 0)
Matej Habrnal fa1950
+            perror_msg("setfscreatecon_raw(NULL)");
Matej Habrnal fa1950
+        else
Matej Habrnal fa1950
+            selinux_fail = 0;
Matej Habrnal fa1950
     }
Matej Habrnal fa1950
+    else
Matej Habrnal fa1950
+        perror_msg("setfscreatecon_raw(%s)", newcon);
Matej Habrnal fa1950
 
Matej Habrnal fa1950
+    /*
Matej Habrnal fa1950
+     * DON'T JUMP OVER THIS REVERT OF THE UID/GID CHANGES
Matej Habrnal fa1950
+     */
Matej Habrnal fa1950
     xsetegid(0);
Matej Habrnal fa1950
     xseteuid(0);
Matej Habrnal fa1950
-    if (user_core_fd < 0
Matej Habrnal fa1950
-     || fstat(user_core_fd, &sb) != 0
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+    if (user_core_fd < 0 || selinux_fail)
Matej Habrnal fa1950
+        goto user_core_fail;
Matej Habrnal fa1950
+
Matej Habrnal fa1950
+    struct stat sb;
Matej Habrnal fa1950
+    if (fstat(user_core_fd, &sb) != 0
Matej Habrnal fa1950
      || !S_ISREG(sb.st_mode)
Matej Habrnal fa1950
      || sb.st_nlink != 1
Matej Habrnal fa1950
      || sb.st_uid != fsuid
Matej Habrnal fa1950
     ) {
Matej Habrnal fa1950
-        if (user_core_fd < 0)
Matej Habrnal fa1950
-            perror_msg("Can't open '%s' at '%s'", core_basename, user_pwd);
Matej Habrnal fa1950
-        else
Matej Habrnal fa1950
-            perror_msg("'%s' at '%s' is not a regular file with link count 1 owned by UID(%d)", core_basename, user_pwd, fsuid);
Matej Habrnal fa1950
+        perror_msg("'%s' at '%s' is not a regular file with link count 1 owned by UID(%d)", core_basename, user_pwd, fsuid);
Matej Habrnal fa1950
         goto user_core_fail;
Matej Habrnal fa1950
     }
Matej Habrnal fa1950
     if (ftruncate(user_core_fd, 0) != 0) {
Matej Habrnal fa1950
-- 
Matej Habrnal fa1950
2.1.0
Matej Habrnal fa1950