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
This commit is contained in:
Corey Farrell
2017-12-18 21:12:47 -05:00
parent 204dd027dd
commit d51837a1b9
4 changed files with 59 additions and 29 deletions

View File

@@ -1573,17 +1573,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);
@@ -1597,6 +1601,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
{
@@ -3051,20 +3056,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;
int mlen = 0;
int maxmbuf = ast_asprintf(&mbuf, CMD_MATCHESARRAY, lf->buffer, ptr);
/* 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);
}
if (!mbuf) {
if (maxmbuf == -1) {
*((char *) lf->cursor) = savechr;
return (char *)(CC_ERROR);
@@ -3077,9 +3072,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;
@@ -3092,6 +3087,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';