]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fix handling of negative return code when storing voicemails in ODBC storage
authorMatthew Jordan <mjordan@digium.com>
Mon, 16 Apr 2012 21:40:29 +0000 (21:40 +0000)
committerMatthew Jordan <mjordan@digium.com>
Mon, 16 Apr 2012 21:40:29 +0000 (21:40 +0000)
When storing a voicemail message using an ODBC connection to a database, the
voicemail message is first stored on disk.  The sound file associated with
the message is read into memory before being transmitted to the database.
When this occurs, a failure in the C library's lseek function would cause a
negative value to be passed to the mmap as the size of the memory map to
create.  This would almost certainly cause the creation of the memory map to
fail, resulting in the message being lost.

(issue ASTERISK-19655)
Reported by: Matt Jordan

Review: https://reviewboard.asterisk.org/r/1863
........

Merged revisions 362201 from http://svn.asterisk.org/svn/asterisk/branches/1.8

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@362202 65c4cc65-6c06-0410-ace0-fbb531ad65f3

apps/app_voicemail.c

index 461d7c5e449d8ef1c54de953e06117964c28c164..e872c8b128deebf700bd4be7425eb4f118b35e0c 100644 (file)
@@ -3785,7 +3785,7 @@ static int store_file(const char *dir, const char *mailboxuser, const char *mail
        int res = 0;
        int fd = -1;
        void *fdm = MAP_FAILED;
-       size_t fdlen = -1;
+       off_t fdlen = -1;
        SQLHSTMT stmt;
        char sql[PATH_MAX];
        char msgnums[20];
@@ -3850,11 +3850,14 @@ static int store_file(const char *dir, const char *mailboxuser, const char *mail
                        }
                }
                fdlen = lseek(fd, 0, SEEK_END);
-               lseek(fd, 0, SEEK_SET);
-               printf("Length is %zd\n", fdlen);
+               if (fdlen < 0 || lseek(fd, 0, SEEK_SET) < 0) {
+                       ast_log(AST_LOG_WARNING, "Failed to process sound file '%s': %s\n", full_fn, strerror(errno));
+                       res = -1;
+                       break;
+               }
                fdm = mmap(NULL, fdlen, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
                if (fdm == MAP_FAILED) {
-                       ast_log(AST_LOG_WARNING, "Memory map failed!\n");
+                       ast_log(AST_LOG_WARNING, "Memory map failed for sound file '%s'!\n", full_fn);
                        res = -1;
                        break;
                } 
@@ -4096,8 +4099,7 @@ static int copy(char *infile, char *outfile)
                                close(ifd);
                                close(ofd);
                                unlink(outfile);
-                       }
-                       if (len) {
+                       } else if (len) {
                                res = write(ofd, buf, len);
                                if (errno == ENOMEM || errno == ENOSPC || res != len) {
                                        ast_log(AST_LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));