aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortwilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b>2009-01-14 01:27:18 +0000
committertwilson <twilson@f38db490-d61c-443f-a65b-d21fe96a405b>2009-01-14 01:27:18 +0000
commitb00b6253d2885eedfcd65ad7746077afefa9bbff (patch)
tree7f3c5144853dfd5e0a7cc9bebe12b3d44827f328
parentd5a841f5ab5789d4a6f75e81966e085b5cf5b543 (diff)
Don't overflow when paging more than 128 extensions
The number of available slots for calls in app_page was hardcoded to 128. Proper bounds checking was not in place to enforce this limit, so if more than 128 extensions were passed to the Page() app, Asterisk would crash. This patch instead dynamically allocates memory for the ast_dial structures and removes the (non-functional) arbitrary limit. This issue would have special importance to anyone who is dynamically creating the argument passed to the Page application and allowing more than 128 extensions to be added by an outside user via some external interface. The patch posted by a_villacis was slightly modified for some coding guidelines and other cleanups. Thanks, a_villacis! (closes issue #14217) Reported by: a_villacis Patches: 20080912-asterisk-app_page-fix-buffer-overflow.patch uploaded by a (license 660) Tested by: otherwiseguy git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@168593 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--apps/app_page.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/apps/app_page.c b/apps/app_page.c
index c3c383ea1..f93e5d7c3 100644
--- a/apps/app_page.c
+++ b/apps/app_page.c
@@ -78,18 +78,18 @@ AST_APP_OPTIONS(page_opts, {
AST_APP_OPTION('r', PAGE_RECORD),
});
-#define MAX_DIALS 128
static int page_exec(struct ast_channel *chan, void *data)
{
struct ast_module_user *u;
- char *options, *tech, *resource, *tmp;
+ char *options, *tech, *resource, *tmp, *tmp2;
char meetmeopts[88], originator[AST_CHANNEL_NAME];
struct ast_flags flags = { 0 };
unsigned int confid = ast_random();
struct ast_app *app;
int res = 0, pos = 0, i = 0;
- struct ast_dial *dials[MAX_DIALS];
+ struct ast_dial **dial_list;
+ unsigned int num_dials;
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "This application requires at least one argument (destination(s) to page)\n");
@@ -117,6 +117,19 @@ static int page_exec(struct ast_channel *chan, void *data)
snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe|%ud|%s%sqxdw(5)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"),
(ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") );
+ /* Count number of extensions in list by number of ampersands + 1 */
+ num_dials = 1;
+ tmp2 = tmp;
+ while (*tmp2 && *tmp2++ == '&') {
+ num_dials++;
+ }
+
+ if (!(dial_list = ast_calloc(num_dials, sizeof(void *)))) {
+ ast_log(LOG_ERROR, "Can't allocate %ld bytes for dial list\n", (sizeof(void *) * num_dials));
+ ast_module_user_remove(u);
+ return -1;
+ }
+
/* Go through parsing/calling each device */
while ((tech = strsep(&tmp, "&"))) {
struct ast_dial *dial = NULL;
@@ -149,7 +162,7 @@ static int page_exec(struct ast_channel *chan, void *data)
ast_dial_run(dial, chan, 1);
/* Put in our dialing array */
- dials[pos++] = dial;
+ dial_list[pos++] = dial;
}
if (!ast_test_flag(&flags, PAGE_QUIET)) {
@@ -166,7 +179,7 @@ static int page_exec(struct ast_channel *chan, void *data)
/* Go through each dial attempt cancelling, joining, and destroying */
for (i = 0; i < pos; i++) {
- struct ast_dial *dial = dials[i];
+ struct ast_dial *dial = dial_list[i];
/* We have to wait for the async thread to exit as it's possible Meetme won't throw them out immediately */
ast_dial_join(dial);
@@ -178,6 +191,7 @@ static int page_exec(struct ast_channel *chan, void *data)
ast_dial_destroy(dial);
}
+ ast_free(dial_list);
ast_module_user_remove(u);
return -1;