mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Fixed invalid read and null pointer deref on asterisk shutdown.
In some cases when starting asterisk with -c and hitting control-c to shutdown, there will be an invalid read and null pointer deref causing a crash. (closes issue ASTERISK-17927) Reported by: Mark Murawski Tested by: Mark Murawski, Kinsey Moore, Tilghman Lesher git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@328593 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -288,6 +288,7 @@ static int sig_alert_pipe[2] = { -1, -1 }; | ||||
| static struct { | ||||
| 	 unsigned int need_reload:1; | ||||
| 	 unsigned int need_quit:1; | ||||
| 	 unsigned int need_quit_handler:1; | ||||
| } sig_flags; | ||||
|  | ||||
| #if !defined(LOW_MEMORY) | ||||
| @@ -1652,21 +1653,24 @@ static void quit_handler(int num, int niceness, int safeshutdown, int restart) | ||||
| 			ast_module_shutdown(); | ||||
| 	} | ||||
| 	if (ast_opt_console || (ast_opt_remote && !ast_opt_exec)) { | ||||
| 		pthread_t thisthread = pthread_self(); | ||||
| 		if (getenv("HOME")) { | ||||
| 			snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); | ||||
| 		} | ||||
| 		if (!ast_strlen_zero(filename)) { | ||||
| 			ast_el_write_history(filename); | ||||
| 		} | ||||
| 		if (consolethread == AST_PTHREADT_NULL || consolethread == thisthread || mon_sig_flags == thisthread) { | ||||
| 			/* Only end if we are the consolethread or signal handler, otherwise there's a race with that thread. */ | ||||
| 		if (consolethread == AST_PTHREADT_NULL || consolethread == pthread_self()) { | ||||
| 			/* Only end if we are the consolethread, otherwise there's a race with that thread. */ | ||||
| 			if (el != NULL) { | ||||
| 				el_end(el); | ||||
| 			} | ||||
| 			if (el_hist != NULL) { | ||||
| 				history_end(el_hist); | ||||
| 			} | ||||
| 		} else if (mon_sig_flags == pthread_self()) { | ||||
| 			if (consolethread != AST_PTHREADT_NULL) { | ||||
| 				pthread_kill(consolethread, SIGURG); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	if (option_verbose) | ||||
| @@ -2145,7 +2149,7 @@ static int ast_el_read_char(EditLine *editline, char *cp) | ||||
| 		} | ||||
| 		res = ast_poll(fds, max, -1); | ||||
| 		if (res < 0) { | ||||
| 			if (sig_flags.need_quit) | ||||
| 			if (sig_flags.need_quit || sig_flags.need_quit_handler) | ||||
| 				break; | ||||
| 			if (errno == EINTR) | ||||
| 				continue; | ||||
| @@ -2684,7 +2688,7 @@ static void ast_remotecontrol(char *data) | ||||
| 		sprintf(tmp, "%s%s", prefix, data); | ||||
| 		if (write(ast_consock, tmp, strlen(tmp) + 1) < 0) { | ||||
| 			ast_log(LOG_ERROR, "write() failed: %s\n", strerror(errno)); | ||||
| 			if (sig_flags.need_quit == 1) { | ||||
| 			if (sig_flags.need_quit || sig_flags.need_quit_handler) { | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| @@ -2722,7 +2726,7 @@ static void ast_remotecontrol(char *data) | ||||
| 			char buffer[512] = "", *curline = buffer, *nextline; | ||||
| 			int not_written = 1; | ||||
|  | ||||
| 			if (sig_flags.need_quit == 1) { | ||||
| 			if (sig_flags.need_quit || sig_flags.need_quit_handler) { | ||||
| 				break; | ||||
| 			} | ||||
|  | ||||
| @@ -2770,7 +2774,7 @@ static void ast_remotecontrol(char *data) | ||||
| 	for (;;) { | ||||
| 		ebuf = (char *)el_gets(el, &num); | ||||
|  | ||||
| 		if (sig_flags.need_quit == 1) { | ||||
| 		if (sig_flags.need_quit || sig_flags.need_quit_handler) { | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| @@ -3092,7 +3096,12 @@ static void *monitor_sig_flags(void *unused) | ||||
| 		} | ||||
| 		if (sig_flags.need_quit) { | ||||
| 			sig_flags.need_quit = 0; | ||||
| 			quit_handler(0, 0, 1, 0); | ||||
| 			if (consolethread != AST_PTHREADT_NULL) { | ||||
| 				sig_flags.need_quit_handler = 1; | ||||
| 				pthread_kill(consolethread, SIGURG); | ||||
| 			} else { | ||||
| 				quit_handler(0, 0, 1, 0); | ||||
| 			} | ||||
| 		} | ||||
| 		if (read(sig_alert_pipe[0], &a, sizeof(a)) != sizeof(a)) { | ||||
| 		} | ||||
| @@ -3863,7 +3872,13 @@ int main(int argc, char *argv[]) | ||||
| 		snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %ld)", hostname, (long)ast_mainpid); | ||||
| 		set_title(title); | ||||
|  | ||||
| 		el_set(el, EL_GETCFN, ast_el_read_char); | ||||
|  | ||||
| 		for (;;) { | ||||
| 			if (sig_flags.need_quit || sig_flags.need_quit_handler) { | ||||
| 				quit_handler(0, 0, 0, 0); | ||||
| 				break; | ||||
| 			} | ||||
| 			buf = (char *) el_gets(el, &num); | ||||
|  | ||||
| 			if (!buf && write(1, "", 1) < 0) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user