|
Matej Habrnal |
fa1950 |
From cfc1a5da0a0f2273e0ce39da0c2fa81053ed0eaa Mon Sep 17 00:00:00 2001
|
|
Matej Habrnal |
fa1950 |
From: Jakub Filak <jfilak@redhat.com>
|
|
Matej Habrnal |
fa1950 |
Date: Fri, 17 Apr 2015 16:06:33 +0200
|
|
Matej Habrnal |
fa1950 |
Subject: [PATCH] ccpp: emulate selinux for creation of compat cores
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
This issue was discovered by Florian Weimer of Red Hat Product Security.
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
http://article.gmane.org/gmane.comp.security.selinux/21842
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
Signed-off-by: Jakub Filak <jfilak@redhat.com>
|
|
Matej Habrnal |
fa1950 |
---
|
|
Matej Habrnal |
fa1950 |
configure.ac | 1 +
|
|
Matej Habrnal |
fa1950 |
src/hooks/Makefile.am | 4 ++-
|
|
Matej Habrnal |
fa1950 |
src/hooks/abrt-hook-ccpp.c | 85 ++++++++++++++++++++++++++++++++++++++++++++--
|
|
Matej Habrnal |
fa1950 |
3 files changed, 86 insertions(+), 4 deletions(-)
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
diff --git a/configure.ac b/configure.ac
|
|
Matej Habrnal |
fa1950 |
index d7e0ea5..430f23c 100644
|
|
Matej Habrnal |
fa1950 |
--- a/configure.ac
|
|
Matej Habrnal |
fa1950 |
+++ b/configure.ac
|
|
Matej Habrnal |
fa1950 |
@@ -141,6 +141,7 @@ PKG_CHECK_MODULES([POLKIT], [polkit-gobject-1])
|
|
Matej Habrnal |
fa1950 |
PKG_CHECK_MODULES([GIO], [gio-2.0])
|
|
Matej Habrnal |
fa1950 |
PKG_CHECK_MODULES([SATYR], [satyr])
|
|
Matej Habrnal |
fa1950 |
PKG_CHECK_MODULES([SYSTEMD_JOURNAL], [libsystemd-journal])
|
|
Matej Habrnal |
fa1950 |
+PKG_CHECK_MODULES([LIBSELINUX], [libselinux])
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
PKG_PROG_PKG_CONFIG
|
|
Matej Habrnal |
fa1950 |
AC_ARG_WITH([systemdsystemunitdir],
|
|
Matej Habrnal |
fa1950 |
diff --git a/src/hooks/Makefile.am b/src/hooks/Makefile.am
|
|
Matej Habrnal |
fa1950 |
index 13702b5..ff070cf 100644
|
|
Matej Habrnal |
fa1950 |
--- a/src/hooks/Makefile.am
|
|
Matej Habrnal |
fa1950 |
+++ b/src/hooks/Makefile.am
|
|
Matej Habrnal |
fa1950 |
@@ -33,10 +33,12 @@ abrt_hook_ccpp_CPPFLAGS = \
|
|
Matej Habrnal |
fa1950 |
-DDEFAULT_DUMP_DIR_MODE=$(DEFAULT_DUMP_DIR_MODE) \
|
|
Matej Habrnal |
fa1950 |
$(GLIB_CFLAGS) \
|
|
Matej Habrnal |
fa1950 |
$(LIBREPORT_CFLAGS) \
|
|
Matej Habrnal |
fa1950 |
+ $(LIBSELINUX_CFLAGS) \
|
|
Matej Habrnal |
fa1950 |
-D_GNU_SOURCE
|
|
Matej Habrnal |
fa1950 |
abrt_hook_ccpp_LDADD = \
|
|
Matej Habrnal |
fa1950 |
../lib/libabrt.la \
|
|
Matej Habrnal |
fa1950 |
- $(LIBREPORT_LIBS)
|
|
Matej Habrnal |
fa1950 |
+ $(LIBREPORT_LIBS) \
|
|
Matej Habrnal |
fa1950 |
+ $(LIBSELINUX_LIBS)
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
# abrt-merge-pstoreoops
|
|
Matej Habrnal |
fa1950 |
abrt_merge_pstoreoops_SOURCES = \
|
|
Matej Habrnal |
fa1950 |
diff --git a/src/hooks/abrt-hook-ccpp.c b/src/hooks/abrt-hook-ccpp.c
|
|
Matej Habrnal |
fa1950 |
index 53700e4..9696423 100644
|
|
Matej Habrnal |
fa1950 |
--- a/src/hooks/abrt-hook-ccpp.c
|
|
Matej Habrnal |
fa1950 |
+++ b/src/hooks/abrt-hook-ccpp.c
|
|
Matej Habrnal |
fa1950 |
@@ -20,6 +20,7 @@
|
|
Matej Habrnal |
fa1950 |
*/
|
|
Matej Habrnal |
fa1950 |
#include <sys/utsname.h>
|
|
Matej Habrnal |
fa1950 |
#include "libabrt.h"
|
|
Matej Habrnal |
fa1950 |
+#include <selinux/selinux.h>
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
#ifdef ENABLE_DUMP_TIME_UNWIND
|
|
Matej Habrnal |
fa1950 |
#include <satyr/abrt.h>
|
|
Matej Habrnal |
fa1950 |
@@ -163,12 +164,68 @@ static DIR *open_cwd(pid_t pid)
|
|
Matej Habrnal |
fa1950 |
return cwd;
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
+/* Computes a security context of new file created by the given process with
|
|
Matej Habrnal |
fa1950 |
+ * pid in the given directory represented by file descriptor.
|
|
Matej Habrnal |
fa1950 |
+ *
|
|
Matej Habrnal |
fa1950 |
+ * On errors returns negative number. Returns 0 if the function succeeds and
|
|
Matej Habrnal |
fa1950 |
+ * computes the context and returns positive number and assigns NULL to newcon
|
|
Matej Habrnal |
fa1950 |
+ * if the security context is not needed (SELinux disabled).
|
|
Matej Habrnal |
fa1950 |
+ */
|
|
Matej Habrnal |
fa1950 |
+static int compute_selinux_con_for_new_file(pid_t pid, int dir_fd, security_context_t *newcon)
|
|
Matej Habrnal |
fa1950 |
+{
|
|
Matej Habrnal |
fa1950 |
+ security_context_t srccon;
|
|
Matej Habrnal |
fa1950 |
+ security_context_t dstcon;
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ const int r = is_selinux_enabled();
|
|
Matej Habrnal |
fa1950 |
+ if (r == 0)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ *newcon = NULL;
|
|
Matej Habrnal |
fa1950 |
+ return 1;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+ else if (r == -1)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ perror_msg("Couldn't get state of SELinux");
|
|
Matej Habrnal |
fa1950 |
+ return -1;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+ else if (r != 1)
|
|
Matej Habrnal |
fa1950 |
+ error_msg_and_die("Unexpected SELinux return value: %d", r);
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ if (getpidcon_raw(pid, &srccon) < 0)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ perror_msg("getpidcon_raw(%d)", pid);
|
|
Matej Habrnal |
fa1950 |
+ return -1;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ if (fgetfilecon_raw(dir_fd, &dstcon) < 0)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ perror_msg("getfilecon_raw(%s)", user_pwd);
|
|
Matej Habrnal |
fa1950 |
+ return -1;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ if (security_compute_create_raw(srccon, dstcon, string_to_security_class("file"), newcon) < 0)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ perror_msg("security_compute_create_raw(%s, %s, 'file')", srccon, dstcon);
|
|
Matej Habrnal |
fa1950 |
+ return -1;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+ return 0;
|
|
Matej Habrnal |
fa1950 |
+}
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
static int open_user_core(uid_t uid, uid_t fsuid, gid_t fsgid, pid_t pid, char **percent_values)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
proc_cwd = open_cwd(pid);
|
|
Matej Habrnal |
fa1950 |
if (proc_cwd == NULL)
|
|
Matej Habrnal |
fa1950 |
return -1;
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
+ /* http://article.gmane.org/gmane.comp.security.selinux/21842 */
|
|
Matej Habrnal |
fa1950 |
+ security_context_t newcon;
|
|
Matej Habrnal |
fa1950 |
+ if (compute_selinux_con_for_new_file(pid, dirfd(proc_cwd), &newcon) < 0)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ log_notice("Not going to create a user core due to SELinux errors");
|
|
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 |
@@ -263,10 +320,25 @@ static int open_user_core(uid_t uid, uid_t fsuid, gid_t fsgid, pid_t pid, char *
|
|
Matej Habrnal |
fa1950 |
* (However, see the description of the prctl(2) PR_SET_DUMPABLE operation,
|
|
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 |
+
|
|
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 |
+ if (newcon != NULL && setfscreatecon_raw(NULL) < 0)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ error_msg("setfscreatecon_raw(NULL)");
|
|
Matej Habrnal |
fa1950 |
+ goto user_core_fail;
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
xsetegid(0);
|
|
Matej Habrnal |
fa1950 |
xseteuid(0);
|
|
Matej Habrnal |
fa1950 |
if (user_core_fd < 0
|
|
Matej Habrnal |
fa1950 |
@@ -279,16 +351,23 @@ static int open_user_core(uid_t uid, uid_t fsuid, gid_t fsgid, pid_t pid, char *
|
|
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 |
- return -1;
|
|
Matej Habrnal |
fa1950 |
+ goto user_core_fail;
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
if (ftruncate(user_core_fd, 0) != 0) {
|
|
Matej Habrnal |
fa1950 |
/* perror first, otherwise unlink may trash errno */
|
|
Matej Habrnal |
fa1950 |
perror_msg("Can't truncate '%s' at '%s' to size 0", core_basename, user_pwd);
|
|
Matej Habrnal |
fa1950 |
- unlinkat(dirfd(proc_cwd), core_basename, /*unlink file*/0);
|
|
Matej Habrnal |
fa1950 |
- return -1;
|
|
Matej Habrnal |
fa1950 |
+ goto user_core_fail;
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
return user_core_fd;
|
|
Matej Habrnal |
fa1950 |
+
|
|
Matej Habrnal |
fa1950 |
+user_core_fail:
|
|
Matej Habrnal |
fa1950 |
+ if (user_core_fd >= 0)
|
|
Matej Habrnal |
fa1950 |
+ {
|
|
Matej Habrnal |
fa1950 |
+ close(user_core_fd);
|
|
Matej Habrnal |
fa1950 |
+ unlinkat(dirfd(proc_cwd), core_basename, /*unlink file*/0);
|
|
Matej Habrnal |
fa1950 |
+ }
|
|
Matej Habrnal |
fa1950 |
+ return -1;
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
/* Like xopen, but on error, unlocks and deletes dd and user core */
|
|
Matej Habrnal |
fa1950 |
--
|
|
Matej Habrnal |
fa1950 |
2.1.0
|
|
Matej Habrnal |
fa1950 |
|