Merged revisions 75445 via svnmerge from

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
This commit is contained in:
Russell Bryant
2007-07-17 20:49:09 +00:00
parent 54bd38f1ce
commit b5ff588044
3 changed files with 21 additions and 11 deletions

View 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