|
Matej Habrnal |
fa1950 |
From f15b6e0f53ceb5ba450e93e406272ffe8a398cbd Mon Sep 17 00:00:00 2001
|
|
Matej Habrnal |
fa1950 |
From: Jakub Filak <jfilak@redhat.com>
|
|
Matej Habrnal |
fa1950 |
Date: Mon, 1 Jun 2015 12:03:55 +0200
|
|
Matej Habrnal |
fa1950 |
Subject: [PATCH] hooks: use root for owner of all dump directories
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
This patch has two goals:
|
|
Matej Habrnal |
fa1950 |
* avoid hard and symbolic link attacks (race conditions)
|
|
Matej Habrnal |
fa1950 |
* keep security sensitive data private (in the near future, a problem
|
|
Matej Habrnal |
fa1950 |
directories will contain elements accessible by privileged
|
|
Matej Habrnal |
fa1950 |
users while the directory itself will be accessible by
|
|
Matej Habrnal |
fa1950 |
non-privileged users (dmesg, journald, /var/log/messages)
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
Related: #1212868 (CVE-2015-1870), #1212861 (CVE-2015-1869)
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
Signed-off-by: Jakub Filak <jfilak@redhat.com>
|
|
Matej Habrnal |
fa1950 |
---
|
|
Matej Habrnal |
fa1950 |
src/daemon/abrt-server.c | 2 +-
|
|
Matej Habrnal |
fa1950 |
src/dbus/abrt-dbus.c | 11 ++++-------
|
|
Matej Habrnal |
fa1950 |
src/hooks/abrt-hook-ccpp.c | 18 +++++++++---------
|
|
Matej Habrnal |
fa1950 |
src/lib/hooklib.c | 2 +-
|
|
Matej Habrnal |
fa1950 |
src/plugins/abrt-dump-xorg.c | 15 ++++-----------
|
|
Matej Habrnal |
fa1950 |
src/plugins/oops-utils.c | 15 ++++-----------
|
|
Matej Habrnal |
fa1950 |
6 files changed, 23 insertions(+), 40 deletions(-)
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
diff --git a/src/daemon/abrt-server.c b/src/daemon/abrt-server.c
|
|
Matej Habrnal |
fa1950 |
index 90339ab..d7556e2 100644
|
|
Matej Habrnal |
fa1950 |
--- a/src/daemon/abrt-server.c
|
|
Matej Habrnal |
fa1950 |
+++ b/src/daemon/abrt-server.c
|
|
Matej Habrnal |
fa1950 |
@@ -391,7 +391,7 @@ static int create_problem_dir(GHashTable *problem_info, unsigned pid)
|
|
Matej Habrnal |
fa1950 |
/* No need to check the path length, as all variables used are limited,
|
|
Matej Habrnal |
fa1950 |
* and dd_create() fails if the path is too long.
|
|
Matej Habrnal |
fa1950 |
*/
|
|
Matej Habrnal |
fa1950 |
- struct dump_dir *dd = dd_create(path, client_uid, DEFAULT_DUMP_DIR_MODE);
|
|
Matej Habrnal |
fa1950 |
+ struct dump_dir *dd = dd_create(path, /*fs owner*/0, DEFAULT_DUMP_DIR_MODE);
|
|
Matej Habrnal |
fa1950 |
if (!dd)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
error_msg_and_die("Error creating problem directory '%s'", path);
|
|
Matej Habrnal |
fa1950 |
diff --git a/src/dbus/abrt-dbus.c b/src/dbus/abrt-dbus.c
|
|
Matej Habrnal |
fa1950 |
index 62f331b..44778a2 100644
|
|
Matej Habrnal |
fa1950 |
--- a/src/dbus/abrt-dbus.c
|
|
Matej Habrnal |
fa1950 |
+++ b/src/dbus/abrt-dbus.c
|
|
Matej Habrnal |
fa1950 |
@@ -506,13 +506,10 @@ static void handle_method_call(GDBusConnection *connection,
|
|
Matej Habrnal |
fa1950 |
return;
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- if (ddstat & DD_STAT_OWNED_BY_UID)
|
|
Matej Habrnal |
fa1950 |
- { //caller seems to be in group with access to this dir, so no action needed
|
|
Matej Habrnal |
fa1950 |
- log_notice("caller has access to the requested directory %s", problem_dir);
|
|
Matej Habrnal |
fa1950 |
- g_dbus_method_invocation_return_value(invocation, NULL);
|
|
Matej Habrnal |
fa1950 |
- dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
- return;
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
+ /* It might happen that we will do chowing even if the UID is alreay fs
|
|
Matej Habrnal |
fa1950 |
+ * owner, but DD_STAT_OWNED_BY_UID no longer denotes fs owner and this
|
|
Matej Habrnal |
fa1950 |
+ * method has to ensure file system ownership for the uid.
|
|
Matej Habrnal |
fa1950 |
+ */
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
if ((ddstat & DD_STAT_ACCESSIBLE_BY_UID) == 0 &&
|
|
Matej Habrnal |
fa1950 |
polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
|
|
Matej Habrnal |
fa1950 |
diff --git a/src/hooks/abrt-hook-ccpp.c b/src/hooks/abrt-hook-ccpp.c
|
|
Matej Habrnal |
fa1950 |
index 59fcfce..06dd670 100644
|
|
Matej Habrnal |
fa1950 |
--- a/src/hooks/abrt-hook-ccpp.c
|
|
Matej Habrnal |
fa1950 |
+++ b/src/hooks/abrt-hook-ccpp.c
|
|
Matej Habrnal |
fa1950 |
@@ -707,14 +707,17 @@ int main(int argc, char** argv)
|
|
Matej Habrnal |
fa1950 |
return create_user_core(user_core_fd, pid, ulimit_c);
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- /* use fsuid instead of uid, so we don't expose any sensitive
|
|
Matej Habrnal |
fa1950 |
- * information of suided app in /var/tmp/abrt
|
|
Matej Habrnal |
fa1950 |
+ /* If you don't want to have fs owner as root then:
|
|
Matej Habrnal |
fa1950 |
*
|
|
Matej Habrnal |
fa1950 |
- * dd_create_skeleton() creates a new directory and leaves ownership to
|
|
Matej Habrnal |
fa1950 |
- * the current user, hence, we have to call dd_reset_ownership() after the
|
|
Matej Habrnal |
fa1950 |
- * directory is populated.
|
|
Matej Habrnal |
fa1950 |
+ * - use fsuid instead of uid for fs owner, so we don't expose any
|
|
Matej Habrnal |
fa1950 |
+ * sensitive information of suided app in /var/(tmp|spool)/abrt
|
|
Matej Habrnal |
fa1950 |
+ *
|
|
Matej Habrnal |
fa1950 |
+ * - use dd_create_skeleton() and dd_reset_ownership(), when you finish
|
|
Matej Habrnal |
fa1950 |
+ * creating the new dump directory, to prevent the real owner to write to
|
|
Matej Habrnal |
fa1950 |
+ * the directory until the hook is done (avoid race conditions and defend
|
|
Matej Habrnal |
fa1950 |
+ * hard and symbolic link attacs)
|
|
Matej Habrnal |
fa1950 |
*/
|
|
Matej Habrnal |
fa1950 |
- dd = dd_create_skeleton(path, fsuid, DEFAULT_DUMP_DIR_MODE, /*no flags*/0);
|
|
Matej Habrnal |
fa1950 |
+ dd = dd_create(path, /*fs owner*/0, DEFAULT_DUMP_DIR_MODE);
|
|
Matej Habrnal |
fa1950 |
if (dd)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
char *rootdir = get_rootdir(pid);
|
|
Matej Habrnal |
fa1950 |
@@ -886,9 +889,6 @@ int main(int argc, char** argv)
|
|
Matej Habrnal |
fa1950 |
if (tid > 0 && setting_CreateCoreBacktrace)
|
|
Matej Habrnal |
fa1950 |
create_core_backtrace(tid, executable, signal_no, dd);
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- /* And finally set the right uid and gid */
|
|
Matej Habrnal |
fa1950 |
- dd_reset_ownership(dd);
|
|
Matej Habrnal |
fa1950 |
-
|
|
Matej Habrnal |
fa1950 |
/* We close dumpdir before we start catering for crash storm case.
|
|
Matej Habrnal |
fa1950 |
* Otherwise, delete_dump_dir's from other concurrent
|
|
Matej Habrnal |
fa1950 |
* CCpp's won't be able to delete our dump (their delete_dump_dir
|
|
Matej Habrnal |
fa1950 |
diff --git a/src/lib/hooklib.c b/src/lib/hooklib.c
|
|
Matej Habrnal |
fa1950 |
index 0a8d703..39a6ef4 100644
|
|
Matej Habrnal |
fa1950 |
--- a/src/lib/hooklib.c
|
|
Matej Habrnal |
fa1950 |
+++ b/src/lib/hooklib.c
|
|
Matej Habrnal |
fa1950 |
@@ -410,7 +410,7 @@ char* problem_data_save(problem_data_t *pd)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
load_abrt_conf();
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- struct dump_dir *dd = create_dump_dir_from_problem_data(pd, g_settings_dump_location);
|
|
Matej Habrnal |
fa1950 |
+ struct dump_dir *dd = create_dump_dir_from_problem_data_ext(pd, g_settings_dump_location, /*fs owner*/0);
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
char *problem_id = NULL;
|
|
Matej Habrnal |
fa1950 |
if (dd)
|
|
Matej Habrnal |
fa1950 |
diff --git a/src/plugins/abrt-dump-xorg.c b/src/plugins/abrt-dump-xorg.c
|
|
Matej Habrnal |
fa1950 |
index 3500629..477ec9c 100644
|
|
Matej Habrnal |
fa1950 |
--- a/src/plugins/abrt-dump-xorg.c
|
|
Matej Habrnal |
fa1950 |
+++ b/src/plugins/abrt-dump-xorg.c
|
|
Matej Habrnal |
fa1950 |
@@ -73,15 +73,6 @@ static void save_bt_to_dump_dir(const char *bt, const char *exe, const char *rea
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
time_t t = time(NULL);
|
|
Matej Habrnal |
fa1950 |
const char *iso_date = iso_date_string(&t);
|
|
Matej Habrnal |
fa1950 |
- /* dump should be readable by all if we're run with -x */
|
|
Matej Habrnal |
fa1950 |
- uid_t my_euid = (uid_t)-1L;
|
|
Matej Habrnal |
fa1950 |
- mode_t mode = DEFAULT_DUMP_DIR_MODE | S_IROTH;
|
|
Matej Habrnal |
fa1950 |
- /* and readable only for the owner otherwise */
|
|
Matej Habrnal |
fa1950 |
- if (!(g_opts & OPT_x))
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- mode = DEFAULT_DUMP_DIR_MODE;
|
|
Matej Habrnal |
fa1950 |
- my_euid = geteuid();
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
pid_t my_pid = getpid();
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
@@ -89,10 +80,10 @@ static void save_bt_to_dump_dir(const char *bt, const char *exe, const char *rea
|
|
Matej Habrnal |
fa1950 |
sprintf(base, "xorg-%s-%lu-%u", iso_date, (long)my_pid, g_bt_count);
|
|
Matej Habrnal |
fa1950 |
char *path = concat_path_file(debug_dumps_dir, base);
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- struct dump_dir *dd = dd_create(path, /*uid:*/ my_euid, mode);
|
|
Matej Habrnal |
fa1950 |
+ struct dump_dir *dd = dd_create(path, /*fs owner*/0, DEFAULT_DUMP_DIR_MODE);
|
|
Matej Habrnal |
fa1950 |
if (dd)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
- dd_create_basic_files(dd, /*uid:*/ my_euid, NULL);
|
|
Matej Habrnal |
fa1950 |
+ dd_create_basic_files(dd, /*no uid*/(uid_t)-1L, NULL);
|
|
Matej Habrnal |
fa1950 |
dd_save_text(dd, FILENAME_ABRT_VERSION, VERSION);
|
|
Matej Habrnal |
fa1950 |
dd_save_text(dd, FILENAME_ANALYZER, "xorg");
|
|
Matej Habrnal |
fa1950 |
dd_save_text(dd, FILENAME_TYPE, "xorg");
|
|
Matej Habrnal |
fa1950 |
@@ -111,6 +102,8 @@ static void save_bt_to_dump_dir(const char *bt, const char *exe, const char *rea
|
|
Matej Habrnal |
fa1950 |
exe = "/usr/bin/Xorg";
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
dd_save_text(dd, FILENAME_EXECUTABLE, exe);
|
|
Matej Habrnal |
fa1950 |
+ if (!(g_opts & OPT_x))
|
|
Matej Habrnal |
fa1950 |
+ dd_set_no_owner(dd);
|
|
Matej Habrnal |
fa1950 |
dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
notify_new_path(path);
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
diff --git a/src/plugins/oops-utils.c b/src/plugins/oops-utils.c
|
|
Matej Habrnal |
fa1950 |
index ea6c639..bb6a79c 100644
|
|
Matej Habrnal |
fa1950 |
--- a/src/plugins/oops-utils.c
|
|
Matej Habrnal |
fa1950 |
+++ b/src/plugins/oops-utils.c
|
|
Matej Habrnal |
fa1950 |
@@ -92,15 +92,6 @@ unsigned abrt_oops_create_dump_dirs(GList *oops_list, const char *dump_location,
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
time_t t = time(NULL);
|
|
Matej Habrnal |
fa1950 |
const char *iso_date = iso_date_string(&t);
|
|
Matej Habrnal |
fa1950 |
- /* dump should be readable by all if we're run with -x */
|
|
Matej Habrnal |
fa1950 |
- uid_t my_euid = (uid_t)-1L;
|
|
Matej Habrnal |
fa1950 |
- mode_t mode = DEFAULT_DUMP_DIR_MODE | S_IROTH;
|
|
Matej Habrnal |
fa1950 |
- /* and readable only for the owner otherwise */
|
|
Matej Habrnal |
fa1950 |
- if (!(flags & ABRT_OOPS_WORLD_READABLE))
|
|
Matej Habrnal |
fa1950 |
- {
|
|
Matej Habrnal |
fa1950 |
- mode = DEFAULT_DUMP_DIR_MODE;
|
|
Matej Habrnal |
fa1950 |
- my_euid = geteuid();
|
|
Matej Habrnal |
fa1950 |
- }
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
pid_t my_pid = getpid();
|
|
Matej Habrnal |
fa1950 |
unsigned idx = 0;
|
|
Matej Habrnal |
fa1950 |
@@ -111,10 +102,10 @@ unsigned abrt_oops_create_dump_dirs(GList *oops_list, const char *dump_location,
|
|
Matej Habrnal |
fa1950 |
sprintf(base, "oops-%s-%lu-%lu", iso_date, (long)my_pid, (long)idx);
|
|
Matej Habrnal |
fa1950 |
char *path = concat_path_file(dump_location, base);
|
|
Matej Habrnal |
fa1950 |
|
|
Matej Habrnal |
fa1950 |
- struct dump_dir *dd = dd_create(path, /*uid:*/ my_euid, mode);
|
|
Matej Habrnal |
fa1950 |
+ struct dump_dir *dd = dd_create(path, /*fs owner*/0, DEFAULT_DUMP_DIR_MODE);
|
|
Matej Habrnal |
fa1950 |
if (dd)
|
|
Matej Habrnal |
fa1950 |
{
|
|
Matej Habrnal |
fa1950 |
- dd_create_basic_files(dd, /*uid:*/ my_euid, NULL);
|
|
Matej Habrnal |
fa1950 |
+ dd_create_basic_files(dd, /*no uid*/(uid_t)-1L, NULL);
|
|
Matej Habrnal |
fa1950 |
abrt_oops_save_data_in_dump_dir(dd, (char*)g_list_nth_data(oops_list, idx++), proc_modules);
|
|
Matej Habrnal |
fa1950 |
dd_save_text(dd, FILENAME_ABRT_VERSION, VERSION);
|
|
Matej Habrnal |
fa1950 |
dd_save_text(dd, FILENAME_ANALYZER, "Kerneloops");
|
|
Matej Habrnal |
fa1950 |
@@ -127,6 +118,8 @@ unsigned abrt_oops_create_dump_dirs(GList *oops_list, const char *dump_location,
|
|
Matej Habrnal |
fa1950 |
dd_save_text(dd, "fips_enabled", fips_enabled);
|
|
Matej Habrnal |
fa1950 |
if (suspend_stats)
|
|
Matej Habrnal |
fa1950 |
dd_save_text(dd, "suspend_stats", suspend_stats);
|
|
Matej Habrnal |
fa1950 |
+ if ((flags & ABRT_OOPS_WORLD_READABLE))
|
|
Matej Habrnal |
fa1950 |
+ dd_set_no_owner(dd);
|
|
Matej Habrnal |
fa1950 |
dd_close(dd);
|
|
Matej Habrnal |
fa1950 |
notify_new_path(path);
|
|
Matej Habrnal |
fa1950 |
}
|
|
Matej Habrnal |
fa1950 |
--
|
|
Matej Habrnal |
fa1950 |
2.1.0
|
|
Matej Habrnal |
fa1950 |
|