Merged revisions 75445 via svnmerge from
authorRussell Bryant <russell@russellbryant.com>
Tue, 17 Jul 2007 20:49:09 +0000 (20:49 +0000)
committerRussell Bryant <russell@russellbryant.com>
Tue, 17 Jul 2007 20:49:09 +0000 (20:49 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

................
r75445 | russell | 2007-07-17 15:48:21 -0500 (Tue, 17 Jul 2007) | 13 lines

Merged revisions 75444 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.2

........
r75444 | russell | 2007-07-17 15:45:27 -0500 (Tue, 17 Jul 2007) | 5 lines

Ensure that when encoding the contents of an ast_frame into an iax_frame, that
the size of the destination buffer is known in the iax_frame so that code
won't write past the end of the allocated buffer when sending outgoing frames.
(ASA-2007-014)

........

................

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

channels/chan_iax2.c
channels/iax2-parser.c
channels/iax2-parser.h

index d9bd552..2ed8a36 100644 (file)
@@ -1206,10 +1206,10 @@ static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
 {
        struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
        if (new) {
-               size_t mallocd_datalen = new->mallocd_datalen;
+               size_t afdatalen = new->afdatalen;
                memcpy(new, fr, sizeof(*new));
                iax_frame_wrap(new, &fr->af);
-               new->mallocd_datalen = mallocd_datalen;
+               new->afdatalen = afdatalen;
                new->data = NULL;
                new->datalen = 0;
                new->direction = DIRECTION_INGRESS;
@@ -4045,7 +4045,9 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
        int sendmini=0;
        unsigned int lastsent;
        unsigned int fts;
-               
+
+       frb.fr2.afdatalen = sizeof(frb.buffer);
+
        if (!pvt) {
                ast_log(LOG_WARNING, "No private structure for packet?\n");
                return -1;
@@ -6847,6 +6849,7 @@ static int socket_process(struct iax2_thread *thread)
        /* allocate an iax_frame with 4096 bytes of data buffer */
        fr = alloca(sizeof(*fr) + 4096);
        fr->callno = 0;
+       fr->afdatalen = 4096; /* From alloca() above */
 
        /* Copy frequently used parameters to the stack */
        res = thread->buf_len;
index 7947c7f..7695051 100644 (file)
@@ -974,13 +974,20 @@ void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
        fr->af.data = fr->afdata;
        fr->af.len = f->len;
        if (fr->af.datalen) {
+               size_t copy_len = fr->af.datalen;
+               if (copy_len > fr->afdatalen) {
+                       ast_log(LOG_ERROR, "Losing frame data because destination buffer size '%d' bytes not big enough for '%d' bytes in the frame\n",
+                               (int) fr->afdatalen, (int) fr->af.datalen);
+                       copy_len = fr->afdatalen;
+               }
 #if __BYTE_ORDER == __LITTLE_ENDIAN
                /* We need to byte-swap slinear samples from network byte order */
                if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) {
-                       ast_swapcopy_samples(fr->af.data, f->data, fr->af.samples);
+                       /* 2 bytes / sample for SLINEAR */
+                       ast_swapcopy_samples(fr->af.data, f->data, copy_len / 2);
                } else
 #endif
-               memcpy(fr->af.data, f->data, fr->af.datalen);
+                       memcpy(fr->af.data, f->data, copy_len);
        }
 }
 
@@ -994,11 +1001,11 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
        /* Attempt to get a frame from this thread's cache */
        if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
                AST_LIST_TRAVERSE_SAFE_BEGIN(iax_frames, fr, list) {
-                       if (fr->mallocd_datalen >= datalen) {
-                               size_t mallocd_datalen = fr->mallocd_datalen;
+                       if (fr->afdatalen >= datalen) {
+                               size_t afdatalen = fr->afdatalen;
                                AST_LIST_REMOVE_CURRENT(iax_frames, list);
                                memset(fr, 0, sizeof(*fr));
-                               fr->mallocd_datalen = mallocd_datalen;
+                               fr->afdatalen = afdatalen;
                                break;
                        }
                }
@@ -1007,12 +1014,12 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
        if (!fr) {
                if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
                        return NULL;
-               fr->mallocd_datalen = datalen;
+               fr->afdatalen = datalen;
        }
 #else
        if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
                return NULL;
-       fr->mallocd_datalen = datalen;
+       fr->afdatalen = datalen;
 #endif
 
 
index 076f7ca..e40669d 100644 (file)
@@ -126,7 +126,7 @@ struct iax_frame {
        /* Actual, isolated frame header */
        struct ast_frame af;
        /*! Amount of space _allocated_ for data */
-       size_t mallocd_datalen;
+       size_t afdatalen;
        unsigned char unused[AST_FRIENDLY_OFFSET];
        unsigned char afdata[0];        /* Data for frame */
 };