Merged revisions 236509 via svnmerge from
authorSean Bright <sean@malleable.com>
Mon, 28 Dec 2009 12:44:58 +0000 (12:44 +0000)
committerSean Bright <sean@malleable.com>
Mon, 28 Dec 2009 12:44:58 +0000 (12:44 +0000)
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: https://origsvn.digium.com/svn/asterisk/trunk@236510 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_meetme.c

index 09ec408..335e79f 100644 (file)
@@ -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) */
                                                                        }
                                                                }
                                                        }