From 9adffca9c786c3b62eefd9de519287b9801f9fec Mon Sep 17 00:00:00 2001 From: Corey Farrell Date: Mon, 18 Dec 2017 21:12:47 -0500 Subject: CLI: Address multiple issues. * listen uses the variable `s` for the result from ast_poll() then overwrites it with the result of accept(). Create a separate variable poll_result to avoid confusion since ast_poll does not return a file descriptor. * Resolve fd leak that would occur if setsockopt failed in listen. * Reserve an extra byte while processing completion results from remote daemon. This fixes a bug where completion processing used strstr() on a string that was not '\0' terminated. This was no risk to the Asterisk daemon, the bug was only reachable the remote console process. * Resolve leak in handle_showchan when the channel is not found. * Multiple leaks and a deadlock in pbx_config CLI completion. * Fix leaks in "manager show command". Change-Id: I8f633ceb1714867ae30ef4e421858f77c14485a9 --- main/asterisk.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) (limited to 'main/asterisk.c') diff --git a/main/asterisk.c b/main/asterisk.c index 015c9f35a..f8e31d5a0 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -1695,17 +1695,21 @@ static void *listener(void *unused) int s; socklen_t len; int x; + int poll_result; struct pollfd fds[1]; + for (;;) { - if (ast_socket < 0) + if (ast_socket < 0) { return NULL; + } fds[0].fd = ast_socket; fds[0].events = POLLIN; - s = ast_poll(fds, 1, -1); + poll_result = ast_poll(fds, 1, -1); pthread_testcancel(); - if (s < 0) { - if (errno != EINTR) + if (poll_result < 0) { + if (errno != EINTR) { ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno)); + } continue; } len = sizeof(sunaddr); @@ -1719,6 +1723,7 @@ static void *listener(void *unused) /* turn on socket credentials passing. */ if (setsockopt(s, SOL_SOCKET, SO_PASSCRED, &sckopt, sizeof(sckopt)) < 0) { ast_log(LOG_WARNING, "Unable to turn on socket credentials passing\n"); + close(s); } else #endif { @@ -3195,20 +3200,10 @@ static char *cli_complete(EditLine *editline, int ch) #define CMD_MATCHESARRAY "_COMMAND MATCHESARRAY \"%s\" \"%s\"" char *mbuf; char *new_mbuf; - int mlen = 0, maxmbuf = 2048; - - /* Start with a 2048 byte buffer */ - mbuf = ast_malloc(maxmbuf); - - /* This will run snprintf twice at most. */ - while (mbuf && (mlen = snprintf(mbuf, maxmbuf, CMD_MATCHESARRAY, lf->buffer, ptr)) > maxmbuf) { - /* Return value does not include space for NULL terminator. */ - maxmbuf = mlen + 1; - ast_free(mbuf); - mbuf = ast_malloc(maxmbuf); - } + int mlen = 0; + int maxmbuf = ast_asprintf(&mbuf, CMD_MATCHESARRAY, lf->buffer, ptr); - if (!mbuf) { + if (maxmbuf == -1) { *((char *) lf->cursor) = savechr; return (char *)(CC_ERROR); @@ -3221,9 +3216,9 @@ static char *cli_complete(EditLine *editline, int ch) while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) { if (mlen + 1024 > maxmbuf) { - /* Expand buffer to the next 1024 byte increment. */ + /* Expand buffer to the next 1024 byte increment plus a NULL terminator. */ maxmbuf = mlen + 1024; - new_mbuf = ast_realloc(mbuf, maxmbuf); + new_mbuf = ast_realloc(mbuf, maxmbuf + 1); if (!new_mbuf) { ast_free(mbuf); *((char *) lf->cursor) = savechr; @@ -3236,6 +3231,7 @@ static char *cli_complete(EditLine *editline, int ch) res = read(ast_consock, mbuf + mlen, 1024); if (res > 0) { mlen += res; + mbuf[mlen] = '\0'; } } mbuf[mlen] = '\0'; -- cgit v1.2.3