]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Avoid a crash with large numbers of MeetMe conferences.
authorSean Bright <sean@malleable.com>
Mon, 28 Dec 2009 12:43:36 +0000 (12:43 +0000)
committerSean Bright <sean@malleable.com>
Mon, 28 Dec 2009 12:43:36 +0000 (12:43 +0000)
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: https://origsvn.digium.com/svn/asterisk/branches/1.4@236509 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_meetme.c

index 7a45004598362dbf420545d7bc7bc1b48c6a9989..f05c4ef3aa2ebb23aec1d7933d54ef38006e3721 100644 (file)
@@ -319,6 +319,9 @@ static const char *slatrunk_desc =
 #define MAX_CONFNUM 80
 #define MAX_PIN     80
 
+/* 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
@@ -2563,7 +2566,6 @@ static struct ast_conference *find_conf(struct ast_channel *chan, char *confno,
        struct ast_config *cfg;
        struct ast_variable *var;
        struct ast_conference *cnf;
-       char *parse;
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(confno);
                AST_APP_ARG(pin);
@@ -2602,13 +2604,15 @@ static struct ast_conference *find_conf(struct ast_channel *chan, char *confno,
                                ast_log(LOG_WARNING, "No %s file :(\n", CONFIG_FILE_NAME);
                                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_NONSTANDARD_APP_ARGS(args, parse, ',');
                                if (!strcasecmp(args.confno, confno)) {
                                        /* Bingo it's a valid conference */
@@ -2774,33 +2778,32 @@ static int conf_exec(struct ast_channel *chan, void *data)
                                if (cfg) {
                                        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) */
                                                                        }
                                                                }
                                                        }