]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
app_voicemail: Fix stack overrun in append_mailbox
authorGeorge Joseph <gjoseph@digium.com>
Fri, 21 Sep 2018 19:32:52 +0000 (13:32 -0600)
committerGeorge Joseph <gjoseph@digium.com>
Fri, 21 Sep 2018 21:08:58 +0000 (15:08 -0600)
The append_mailbox function wasn't calculating the correct length
to pass to ast_alloca and it wasn't handling the case where context
might be empty.

Found by the Address Sanitizer.

Change-Id: I7eb51c7bd18a7a8dbdba261462a95cc69e84f161

apps/app_voicemail.c

index c6e501c3b036a59869fcb24480ebdc535ded7fa8..b900c5a3bed32fe043cfa61c582e27155b772767 100644 (file)
@@ -810,11 +810,16 @@ struct baseio {
        unsigned char iobuf[BASEMAXINLINE];
 };
 
+#define MAX_VM_MBOX_ID_LEN (AST_MAX_EXTENSION)
+#define MAX_VM_CONTEXT_LEN (AST_MAX_CONTEXT)
+/* MAX_VM_MAILBOX_LEN allows enough room for the '@' and NULL terminator */
+#define MAX_VM_MAILBOX_LEN (MAX_VM_MBOX_ID_LEN + MAX_VM_CONTEXT_LEN)
+
 /*! Structure for linked list of users
  * Use ast_vm_user_destroy() to free one of these structures. */
 struct ast_vm_user {
-       char context[AST_MAX_CONTEXT];   /*!< Voicemail context */
-       char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox id, unique within vm context */
+       char context[MAX_VM_CONTEXT_LEN];/*!< Voicemail context */
+       char mailbox[MAX_VM_MBOX_ID_LEN];/*!< Mailbox id, unique within vm context */
        char password[80];               /*!< Secret pin code, numbers only */
        char fullname[80];               /*!< Full name, for directory app */
        char *email;                     /*!< E-mail address */
@@ -12357,7 +12362,7 @@ static int append_mailbox(const char *context, const char *box, const char *data
        char *stringp;
        char *s;
        struct ast_vm_user *vmu;
-       char *mailbox_full;
+       char mailbox_full[MAX_VM_MAILBOX_LEN];
        int new = 0, old = 0, urgent = 0;
        char secretfn[PATH_MAX] = "";
 
@@ -12396,10 +12401,10 @@ static int append_mailbox(const char *context, const char *box, const char *data
                read_password_from_file(secretfn, vmu->password, sizeof(vmu->password));
        }
 
-       mailbox_full = ast_alloca(strlen(box) + strlen(context) + 1);
-       strcpy(mailbox_full, box);
-       strcat(mailbox_full, "@");
-       strcat(mailbox_full, context);
+       snprintf(mailbox_full, MAX_VM_MAILBOX_LEN, "%s%s%s",
+               box,
+               ast_strlen_zero(context) ? "" : "@",
+               context);
 
        inboxcount2(mailbox_full, &urgent, &new, &old);
 #ifdef IMAP_STORAGE