[icinga-checkins] icinga.org: icinga-core/fix/security-CVE-2016-9566: Fix possible root privilege escalation during opening logs (CVE-2016-9566 )

git at icinga.org git at icinga.org
Wed Dec 21 11:02:19 CET 2016


Module: icinga-core
Branch: fix/security-CVE-2016-9566
Commit: a0eb8471673b6b1e9b37e1b7b91151aa00bedb65
URL:    https://git.icinga.org/?p=icinga-core.git;a=commit;h=a0eb8471673b6b1e9b37e1b7b91151aa00bedb65

Author: John C. Frickson <jfrickson at nagios.com>
Date:   Wed Dec 21 10:35:38 2016 +0100

Fix possible root privilege escalation during opening logs (CVE-2016-9566)

Backported change from Nagios Core.

Note: This bug affects Icinga 1.x only for opening a debug log, or when
a config error gets logged on startup.

https://legalhackers.com/advisories/Nagios-Exploit-Root-PrivEsc-CVE-2016-9566.html

Thanks to Dawid Golunski for raising awareness.

Thanks to John C. Frickson (Nagios) for fixing.

Signed-off-by: Markus Frosch <markus.frosch at icinga.com>

refs #13709

---

 THANKS         |    1 +
 base/logging.c |   56 +++++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 48 insertions(+), 9 deletions(-)

diff --git a/THANKS b/THANKS
index 9551d5d..4b0397b 100644
--- a/THANKS
+++ b/THANKS
@@ -361,3 +361,4 @@ in various ways.  If we missed your name, let us know.
 * Dennis van Zuijlekom
 * Pawel Zuzelski
 * Imri Zvik
+* Dawid Golunski (http://legalhackers.com)
diff --git a/base/logging.c b/base/logging.c
index 74969ab..cc02450 100644
--- a/base/logging.c
+++ b/base/logging.c
@@ -216,21 +216,42 @@ static void write_to_all_logs_with_timestamp(char *buffer, unsigned long data_ty
 }
 
 
-FILE *open_log_file(void) {
+FILE *open_log_file(void)
+{
+	int fh;
+	struct stat st;
 
 	if (log_fp) /* keep it open unless we rotate */
 		return log_fp;
 
-	log_fp = fopen(log_file, "a+");
-
+	if ((fh = open(log_file, O_RDWR|O_APPEND|O_CREAT|O_NOFOLLOW, S_IRUSR|S_IWUSR)) == -1) {
+		if (daemon_mode == FALSE)
+			printf("Warning: Cannot open log file '%s' for writing\n", log_file);
+		return NULL;
+	}
+	log_fp = fdopen(fh, "a+");
 	if (log_fp == NULL) {
-		if (daemon_mode == FALSE) {
+		if (daemon_mode == FALSE)
 			printf("Warnings: Cannot open log file '%s' for writing\n", log_file);
-		}
 		return NULL;
 	}
 
-	(void)fcntl(fileno(log_fp), F_SETFD, FD_CLOEXEC);
+	if ((fstat(fh, &st)) == -1) {
+		log_fp = NULL;
+		close(fh);
+		if (daemon_mode == FALSE)
+			printf("Warning: Cannot fstat log file '%s'\n", log_file);
+		return NULL;
+	}
+	if (st.st_nlink != 1 || (st.st_mode & S_IFMT) != S_IFREG) {
+		log_fp = NULL;
+		close(fh);
+		if (daemon_mode == FALSE)
+			printf("Warning: log file '%s' has an invalid mode\n", log_file);
+		return NULL;
+	}
+
+	(void)fcntl(fh, F_SETFD, FD_CLOEXEC);
 
 	return log_fp;
 }
@@ -615,7 +636,10 @@ int write_log_file_info(time_t *timestamp) {
 
 
 /* opens the debug log for writing */
-int open_debug_log(void) {
+int open_debug_log(void)
+{
+   int fh;
+   struct stat st;
 
 	/* don't do anything if we're not actually running... */
 	if (verify_config == TRUE || test_scheduling == TRUE)
@@ -625,10 +649,24 @@ int open_debug_log(void) {
 	if (debug_level == DEBUGL_NONE)
 		return OK;
 
-	if ((debug_file_fp = fopen(debug_file, "a+")) == NULL)
+	if ((fh = open(debug_file, O_RDWR|O_APPEND|O_CREAT|O_NOFOLLOW, S_IRUSR|S_IWUSR)) == -1) {
+		return ERROR;
+	}
+	if ((debug_file_fp = fdopen(fh, "a+")) == NULL)
+		return ERROR;
+
+	if ((fstat(fh, &st)) == -1) {
+		debug_file_fp = NULL;
+		close(fh);
+		return ERROR;
+	}
+	if (st.st_nlink != 1 || (st.st_mode & S_IFMT) != S_IFREG) {
+		debug_file_fp = NULL;
+		close(fh);
 		return ERROR;
+	}
 
-	(void)fcntl(fileno(debug_file_fp), F_SETFD, FD_CLOEXEC);
+	(void)fcntl(fh, F_SETFD, FD_CLOEXEC);
 
 	return OK;
 }



More information about the icinga-checkins mailing list