From 2b1fa2caf4ef3cb253e931f53b43fc9499661da4 Mon Sep 17 00:00:00 2001 From: Jakub Filak Date: Thu, 16 Apr 2015 11:12:40 +0200 Subject: [PATCH] turn off exploring crashed process's root directories A local user can arrange a process root directory in way that abrt will make a copy of file not accessible by the attacker. I don't want to remove the chroot code entirely because it might be useful for non-production environments. Related: #1211835 Signed-off-by: Jakub Filak --- src/daemon/abrt-action-save-package-data.c | 6 +++++- src/daemon/abrt.conf | 16 ++++++++++++++++ src/hooks/abrt-hook-ccpp.c | 12 +++++++++++- src/include/libabrt.h | 2 ++ src/lib/abrt_conf.c | 10 ++++++++++ 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/daemon/abrt-action-save-package-data.c b/src/daemon/abrt-action-save-package-data.c index cc86327..816e0d0 100644 --- a/src/daemon/abrt-action-save-package-data.c +++ b/src/daemon/abrt-action-save-package-data.c @@ -239,7 +239,11 @@ static int SavePackageDescriptionToDebugDump(const char *dump_dir_name) cmdline = dd_load_text_ext(dd, FILENAME_CMDLINE, DD_FAIL_QUIETLY_ENOENT); executable = dd_load_text(dd, FILENAME_EXECUTABLE); - rootdir = dd_load_text_ext(dd, FILENAME_ROOTDIR, + + /* Do not implicitly query rpm database in process's root dir, if + * ExploreChroots is disabled. */ + if (g_settings_explorechroots) + rootdir = dd_load_text_ext(dd, FILENAME_ROOTDIR, DD_FAIL_QUIETLY_ENOENT | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE); /* Close dd while we query package database. It can take some time, diff --git a/src/daemon/abrt.conf b/src/daemon/abrt.conf index 59d1831..02e969d 100644 --- a/src/daemon/abrt.conf +++ b/src/daemon/abrt.conf @@ -43,3 +43,19 @@ AutoreportingEnabled = no # session; otherwise No. # # ShortenedReporting = yes + +# Enables various features exploring process's root directories if they differ +# from the default root directory. The folowing list includes examples of +# enabled features: +# * query the rpm database in the process's root directory +# * save files like /etc/os-release from the process's root directory +# +# This feature is disabled by default because it might be used by a local user +# to steal your data. +# +# Caution: +# +# THIS FEATURE MIGHT BE USED BY A LOCAL USER TO STEEL YOUR DATA BY ARRANGING A +# SPECIAL ROOT DIRECTORY IN USER MOUNT NAMESAPCE +# +# ExploreChroots = false diff --git a/src/hooks/abrt-hook-ccpp.c b/src/hooks/abrt-hook-ccpp.c index e1d81b6..7626a97 100644 --- a/src/hooks/abrt-hook-ccpp.c +++ b/src/hooks/abrt-hook-ccpp.c @@ -601,7 +601,17 @@ int main(int argc, char** argv) { char *rootdir = get_rootdir(pid); - dd_create_basic_files(dd, fsuid, (rootdir && strcmp(rootdir, "/") != 0) ? rootdir : NULL); + /* Reading data from an arbitrary root directory is not secure. */ + if (g_settings_explorechroots) + { + /* Yes, test 'rootdir' but use 'source_filename' because 'rootdir' can + * be '/' for a process with own namespace. 'source_filename' is /proc/[pid]/root. */ + dd_create_basic_files(dd, fsuid, (rootdir != NULL) ? rootdir : NULL); + } + else + { + dd_create_basic_files(dd, fsuid, NULL); + } char source_filename[sizeof("/proc/%lu/somewhat_long_name") + sizeof(long)*3]; int source_base_ofs = sprintf(source_filename, "/proc/%lu/smaps", (long)pid); diff --git a/src/include/libabrt.h b/src/include/libabrt.h index 65d30a1..abfbc97 100644 --- a/src/include/libabrt.h +++ b/src/include/libabrt.h @@ -62,6 +62,8 @@ extern bool g_settings_autoreporting; extern char * g_settings_autoreporting_event; #define g_settings_shortenedreporting abrt_g_settings_shortenedreporting extern bool g_settings_shortenedreporting; +#define g_settings_explorechroots abrt_g_settings_explorechroots +extern bool g_settings_explorechroots; #define load_abrt_conf abrt_load_abrt_conf diff --git a/src/lib/abrt_conf.c b/src/lib/abrt_conf.c index f7fdc6d..46ff689 100644 --- a/src/lib/abrt_conf.c +++ b/src/lib/abrt_conf.c @@ -27,6 +27,7 @@ bool g_settings_delete_uploaded = 0; bool g_settings_autoreporting = 0; char * g_settings_autoreporting_event = NULL; bool g_settings_shortenedreporting = 0; +bool g_settings_explorechroots = 0; void free_abrt_conf_data() { @@ -106,6 +107,15 @@ static void ParseCommon(map_string_t *settings, const char *conf_filename) g_settings_shortenedreporting = (desktop_env && strcasestr(desktop_env, "gnome") != NULL); } + value = get_map_string_item_or_NULL(settings, "ExploreChroots"); + if (value) + { + g_settings_explorechroots = string_to_bool(value); + remove_map_string_item(settings, "ExploreChroots"); + } + else + g_settings_explorechroots = false; + GHashTableIter iter; const char *name; /*char *value; - already declared */ -- 2.1.0