diff options
author | seanbright <seanbright@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-12-28 12:44:58 +0000 |
---|---|---|
committer | seanbright <seanbright@f38db490-d61c-443f-a65b-d21fe96a405b> | 2009-12-28 12:44:58 +0000 |
commit | e6d6f98a5bc65124f0087b48124219c4895c5076 (patch) | |
tree | 7f80907ca563945a18d350a21b21e5fc1154c032 /apps/app_meetme.c | |
parent | 8d4e963cc495ec5f41a3d2e36d75220d77be91c8 (diff) |
Merged revisions 236509 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r236509 | seanbright | 2009-12-28 07:43:36 -0500 (Mon, 28 Dec 2009) | 12 lines
Avoid a crash with large numbers of MeetMe conferences.
Similar to changes made to Queue(), when we have large numbers of conferences in
meetme.conf (1000s) and we use alloca()/strdupa(), we can blow out the stack and
crash, so instead just use a single fixed buffer.
(closes issue #16509)
Reported by: Kashif Raza
Patches:
20091223_16509.patch uploaded by seanbright (license 71)
Tested by: seanbright
........
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@236510 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_meetme.c')
-rw-r--r-- | apps/app_meetme.c | 64 |
1 files changed, 34 insertions, 30 deletions
diff --git a/apps/app_meetme.c b/apps/app_meetme.c index 09ec408e4..335e79f22 100644 --- a/apps/app_meetme.c +++ b/apps/app_meetme.c @@ -671,6 +671,9 @@ static int rt_log_members; #define MAX_PIN 80 #define OPTIONS_LEN 100 +/* Enough space for "<conference #>,<pin>,<admin pin>" followed by a 0 byte. */ +#define MAX_SETTINGS (MAX_CONFNUM + MAX_PIN + MAX_PIN + 3) + enum announcetypes { CONF_HASJOIN, CONF_HASLEFT @@ -3662,7 +3665,7 @@ static struct ast_conference *find_conf(struct ast_channel *chan, char *confno, struct ast_variable *var; struct ast_flags config_flags = { 0 }; struct ast_conference *cnf; - char *parse; + AST_DECLARE_APP_ARGS(args, AST_APP_ARG(confno); AST_APP_ARG(pin); @@ -3706,13 +3709,15 @@ static struct ast_conference *find_conf(struct ast_channel *chan, char *confno, ast_log(LOG_ERROR, "Config file " CONFIG_FILE_NAME " is in an invalid format. Aborting.\n"); return NULL; } + for (var = ast_variable_browse(cfg, "rooms"); var; var = var->next) { + char parse[MAX_SETTINGS]; + if (strcasecmp(var->name, "conf")) continue; - - if (!(parse = ast_strdupa(var->value))) - return NULL; - + + ast_copy_string(parse, var->value, sizeof(parse)); + AST_STANDARD_APP_ARGS(args, parse); ast_debug(3, "Will conf %s match %s?\n", confno, args.confno); if (!strcasecmp(args.confno, confno)) { @@ -3874,33 +3879,32 @@ static int conf_exec(struct ast_channel *chan, const char *data) if (cfg && cfg != CONFIG_STATUS_FILEINVALID) { var = ast_variable_browse(cfg, "rooms"); while (var) { + char parse[MAX_SETTINGS], *stringp = parse, *confno_tmp; if (!strcasecmp(var->name, "conf")) { - char *stringp = ast_strdupa(var->value); - if (stringp) { - char *confno_tmp = strsep(&stringp, "|,"); - int found = 0; - if (!dynamic) { - /* For static: run through the list and see if this conference is empty */ - AST_LIST_LOCK(&confs); - AST_LIST_TRAVERSE(&confs, cnf, list) { - if (!strcmp(confno_tmp, cnf->confno)) { - /* The conference exists, therefore it's not empty */ - found = 1; - break; - } + int found = 0; + ast_copy_string(parse, var->value, sizeof(parse)); + confno_tmp = strsep(&stringp, "|,"); + if (!dynamic) { + /* For static: run through the list and see if this conference is empty */ + AST_LIST_LOCK(&confs); + AST_LIST_TRAVERSE(&confs, cnf, list) { + if (!strcmp(confno_tmp, cnf->confno)) { + /* The conference exists, therefore it's not empty */ + found = 1; + break; } - AST_LIST_UNLOCK(&confs); - if (!found) { - /* At this point, we have a confno_tmp (static conference) that is empty */ - if ((empty_no_pin && ast_strlen_zero(stringp)) || (!empty_no_pin)) { - /* Case 1: empty_no_pin and pin is nonexistent (NULL) - * Case 2: empty_no_pin and pin is blank (but not NULL) - * Case 3: not empty_no_pin - */ - ast_copy_string(confno, confno_tmp, sizeof(confno)); - break; - /* XXX the map is not complete (but we do have a confno) */ - } + } + AST_LIST_UNLOCK(&confs); + if (!found) { + /* At this point, we have a confno_tmp (static conference) that is empty */ + if ((empty_no_pin && ast_strlen_zero(stringp)) || (!empty_no_pin)) { + /* Case 1: empty_no_pin and pin is nonexistent (NULL) + * Case 2: empty_no_pin and pin is blank (but not NULL) + * Case 3: not empty_no_pin + */ + ast_copy_string(confno, confno_tmp, sizeof(confno)); + break; + /* XXX the map is not complete (but we do have a confno) */ } } } |