CVE-2017-12847: Improper Initialization (CWE-665)
value: Nagios Core before 4.3.3 creates a nagios.lock PID file after dropping privileges to a non-root account, which might allow local users to kill arbitrary processes by leveraging access to this non-root account for nagios.lock modification before a root script executes a "kill `cat /pathname/nagios.lock`" command.
CWE description: The product does not initialize or incorrectly initializes a resource, which might leave the resource in an unexpected state when it is accessed or used.
CVSS v3 base score: 6.3
Published: 2017-08-23T21:29Z
Repository: https://github.com/NagiosEnterprises/nagioscore
Language: Other
Files changed: Changelog, THANKS, base/nagios.c, configure.ac
Commit date: 2017-07-30 16:28:11 -0500
Commit message: halfway revert hack/configure changes - switch order of daemon_init/drop_privileges

Diff: diff --git a/Changelog b/Changelog
index a4a528ff..440a443f 100644
--- a/Changelog
+++ b/Changelog
@@ -6,10 +6,12 @@ Nagios Core 4 Change Log
 ------------------
 * xodtemplate.c wrong option-deprecation code warning (alex2grad / John Frickson)
 * On-demand host check always use cached host state (John Frickson)
 * 'á' causes Serivce Status Information to not be displayed (John Frickson)
 * New Macro(s) to generate URL for host / service object (John Frickson)
+* Fix minor map issues (Troy Lea)
+* Fix lockfile issues (Bryan Heden)
 
 
 4.3.2 - 2017-05-09
 ------------------
 FIXED
diff --git a/THANKS b/THANKS
index 92fbf3e9..dddba66b 100644
--- a/THANKS
+++ b/THANKS
@@ -318,10 +318,11 @@ wrong, please let me know.
 * Tom De Blende
 * Tom Welsh
 * Tomer Okavi
 * Ton Voon
 * Torsten Huebler
+* Troy Lea
 * Tyler Lund
 * Uwe Knop
 * Uwe Knop
 * Vadim Okun
 * Volkan Yazici
diff --git a/base/nagios.c b/base/nagios.c
index 26787002..6811aa6c 100644
--- a/base/nagios.c
+++ b/base/nagios.c
@@ -590,10 +590,26 @@ int main(int argc, char **argv) {
 			/* NOTE 11/06/07 EG moved to after we read config files, as user may have overridden timezone offset */
 			/* get program (re)start time and save as macro */
 			program_start = time(NULL);
 			my_free(mac->x[MACRO_PROCESSSTARTTIME]);
 			asprintf(&mac->x[MACRO_PROCESSSTARTTIME], "%llu", (unsigned long long)program_start);
+			
+			/* enter daemon mode (unless we're restarting...) */
+			if(daemon_mode == TRUE && sigrestart == FALSE) {
+
+				result = daemon_init();
+
+				/* we had an error daemonizing, so bail... */
+				if(result == ERROR) {
+					logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to failure to daemonize. (PID=%d)", (int)getpid());
+					cleanup();
+					exit(EXIT_FAILURE);
+					}
+
+				/* get new PID */
+				nagios_pid = (int)getpid();
+				}
 
 			/* drop privileges */
 			if(drop_privileges(nagios_user, nagios_group) == ERROR) {
 
 				logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR | NSLOG_CONFIG_ERROR, TRUE, "Failed to drop privileges.  Aborting.");
@@ -610,25 +626,10 @@ int main(int argc, char **argv) {
 
 			if (test_configured_paths() == ERROR) {
 				/* error has already been logged */
 				exit(EXIT_FAILURE);
 				}
-			/* enter daemon mode (unless we're restarting...) */
-			if(daemon_mode == TRUE && sigrestart == FALSE) {
-
-				result = daemon_init();
-
-				/* we had an error daemonizing, so bail... */
-				if(result == ERROR) {
-					logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to failure to daemonize. (PID=%d)", (int)getpid());
-					cleanup();
-					exit(EXIT_FAILURE);
-					}
-
-				/* get new PID */
-				nagios_pid = (int)getpid();
-				}
 
 			/* this must be logged after we read config data, as user may have changed location of main log file */
 			logit(NSLOG_PROCESS_INFO, TRUE, "Nagios %s starting... (PID=%d)\n", PROGRAM_VERSION, (int)getpid());
 
 			/* log the local time - may be different than clock time due to timezone offset */
diff --git a/configure.ac b/configure.ac
index 15a0a6b0..c21ee0d1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -225,10 +225,11 @@ AC_ARG_WITH(checkresult-dir,
 	CHECKRESULTDIR=no
 ) 
 if test x$CHECKRESULTDIR = xno; then
 	CHECKRESULTDIR="$localstatedir/spool/checkresults"
 fi 
+AC_SUBST(CHECKRESULTDIR)
 
 dnl Location of check result path
 TMPDIR=no
 AC_ARG_WITH(temp-dir,
 	AC_HELP_STRING([--with-temp-dir=<path>],
@@ -268,11 +269,11 @@ AC_ARG_WITH(lockfile,
 	AC_HELP_STRING([--with-lockfile=<path>],
 		[sets path and file name for lock file]),
 	lockfile=$withval,
 	lockfile=$localstatedir/nagios.lock
 )
-
+AC_SUBST(lockfile)
 
 dnl Determine the library to be used by the iobroker
 
 dnl epoll_*() is linux specific and was added to glibc 2.3.2, so we
 dnl check for 2.4 and use epoll() if we're on that version or later.
@@ -817,17 +818,10 @@ perl subst sample-config/template-object/localhost.cfg
 perl subst sample-config/template-object/windows.cfg
 perl subst sample-config/template-object/printer.cfg
 perl subst sample-config/template-object/switch.cfg
 
 
-
-eval localstatedir=$localstatedir
-eval lockfile=$lockfile
-eval CHECKRESULTDIR=$CHECKRESULTDIR
-AC_SUBST(CHECKRESULTDIR)
-AC_SUBST(lockfile)
-
 dnl Review options
 echo ""
 echo ""
 AC_MSG_RESULT([*** Configuration summary for $PKG_NAME $PKG_VERSION $PKG_REL_DATE ***:])
 

Vulnerable code: 			/* enter daemon mode (unless we're restarting...) */
			if(daemon_mode == TRUE && sigrestart == FALSE) {

				result = daemon_init();

				/* we had an error daemonizing, so bail... */
				if(result == ERROR) {
					logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to failure to daemonize. (PID=%d)", (int)getpid());
					cleanup();
					exit(EXIT_FAILURE);
					}

				/* get new PID */
				nagios_pid = (int)getpid();
				}


eval localstatedir=$localstatedir
eval lockfile=$lockfile
eval CHECKRESULTDIR=$CHECKRESULTDIR
AC_SUBST(CHECKRESULTDIR)
AC_SUBST(lockfile)

Fixed code: * Fix minor map issues (Troy Lea)
* Fix lockfile issues (Bryan Heden)
* Troy Lea
			
			/* enter daemon mode (unless we're restarting...) */
			if(daemon_mode == TRUE && sigrestart == FALSE) {

				result = daemon_init();

				/* we had an error daemonizing, so bail... */
				if(result == ERROR) {
					logit(NSLOG_PROCESS_INFO | NSLOG_RUNTIME_ERROR, TRUE, "Bailing out due to failure to daemonize. (PID=%d)", (int)getpid());
					cleanup();
					exit(EXIT_FAILURE);
					}

				/* get new PID */
				nagios_pid = (int)getpid();
				}
AC_SUBST(CHECKRESULTDIR)
AC_SUBST(lockfile)