diff options
author | Corey Farrell <git@cfware.com> | 2017-12-18 21:12:47 -0500 |
---|---|---|
committer | Corey Farrell <git@cfware.com> | 2017-12-19 16:43:32 -0500 |
commit | 9adffca9c786c3b62eefd9de519287b9801f9fec (patch) | |
tree | b0345aa0e012411c0ddaed4d8c570af2a052e755 /main/asterisk.c | |
parent | dba037d42263288d80a8c98a8b010d7f6721305a (diff) |
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
Diffstat (limited to 'main/asterisk.c')
-rw-r--r-- | main/asterisk.c | 34 |
1 files changed, 15 insertions, 19 deletions
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'; |