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/branches/1.4@75445 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.4
Russell Bryant 18 years ago
parent 2193734456
commit 89497599be

@ -1121,10 +1121,10 @@ static struct iax_frame *iaxfrdup2(struct iax_frame *fr)
{ {
struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable); struct iax_frame *new = iax_frame_new(DIRECTION_INGRESS, fr->af.datalen, fr->cacheable);
if (new) { if (new) {
size_t mallocd_datalen = new->mallocd_datalen; size_t afdatalen = new->afdatalen;
memcpy(new, fr, sizeof(*new)); memcpy(new, fr, sizeof(*new));
iax_frame_wrap(new, &fr->af); iax_frame_wrap(new, &fr->af);
new->mallocd_datalen = mallocd_datalen; new->afdatalen = afdatalen;
new->data = NULL; new->data = NULL;
new->datalen = 0; new->datalen = 0;
new->direction = DIRECTION_INGRESS; new->direction = DIRECTION_INGRESS;
@ -3878,6 +3878,8 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
unsigned int lastsent; unsigned int lastsent;
unsigned int fts; unsigned int fts;
frb.fr2.afdatalen = sizeof(frb.buffer);
if (!pvt) { if (!pvt) {
ast_log(LOG_WARNING, "No private structure for packet?\n"); ast_log(LOG_WARNING, "No private structure for packet?\n");
return -1; return -1;
@ -6462,6 +6464,7 @@ static int socket_process(struct iax2_thread *thread)
/* allocate an iax_frame with 4096 bytes of data buffer */ /* allocate an iax_frame with 4096 bytes of data buffer */
fr = alloca(sizeof(*fr) + 4096); fr = alloca(sizeof(*fr) + 4096);
fr->callno = 0; fr->callno = 0;
fr->afdatalen = 4096; /* From alloca() above */
/* Copy frequently used parameters to the stack */ /* Copy frequently used parameters to the stack */
res = thread->buf_len; res = thread->buf_len;

@ -931,13 +931,20 @@ void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
fr->af.data = fr->afdata; fr->af.data = fr->afdata;
fr->af.len = f->len; fr->af.len = f->len;
if (fr->af.datalen) { 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 #if __BYTE_ORDER == __LITTLE_ENDIAN
/* We need to byte-swap slinear samples from network byte order */ /* We need to byte-swap slinear samples from network byte order */
if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass == AST_FORMAT_SLINEAR)) { 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 } else
#endif #endif
memcpy(fr->af.data, f->data, fr->af.datalen); memcpy(fr->af.data, f->data, copy_len);
} }
} }
@ -951,11 +958,11 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
/* Attempt to get a frame from this thread's cache */ /* Attempt to get a frame from this thread's cache */
if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) { if ((iax_frames = ast_threadstorage_get(&frame_cache, sizeof(*iax_frames)))) {
AST_LIST_TRAVERSE_SAFE_BEGIN(iax_frames, fr, list) { AST_LIST_TRAVERSE_SAFE_BEGIN(iax_frames, fr, list) {
if (fr->mallocd_datalen >= datalen) { if (fr->afdatalen >= datalen) {
size_t mallocd_datalen = fr->mallocd_datalen; size_t afdatalen = fr->afdatalen;
AST_LIST_REMOVE_CURRENT(iax_frames, list); AST_LIST_REMOVE_CURRENT(iax_frames, list);
memset(fr, 0, sizeof(*fr)); memset(fr, 0, sizeof(*fr));
fr->mallocd_datalen = mallocd_datalen; fr->afdatalen = afdatalen;
break; break;
} }
} }
@ -964,12 +971,12 @@ struct iax_frame *iax_frame_new(int direction, int datalen, unsigned int cacheab
if (!fr) { if (!fr) {
if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen))) if (!(fr = ast_calloc_cache(1, sizeof(*fr) + datalen)))
return NULL; return NULL;
fr->mallocd_datalen = datalen; fr->afdatalen = datalen;
} }
#else #else
if (!(fr = ast_calloc(1, sizeof(*fr) + datalen))) if (!(fr = ast_calloc(1, sizeof(*fr) + datalen)))
return NULL; return NULL;
fr->mallocd_datalen = datalen; fr->afdatalen = datalen;
#endif #endif

@ -123,7 +123,7 @@ struct iax_frame {
/* Actual, isolated frame header */ /* Actual, isolated frame header */
struct ast_frame af; struct ast_frame af;
/*! Amount of space _allocated_ for data */ /*! Amount of space _allocated_ for data */
size_t mallocd_datalen; size_t afdatalen;
unsigned char unused[AST_FRIENDLY_OFFSET]; unsigned char unused[AST_FRIENDLY_OFFSET];
unsigned char afdata[0]; /* Data for frame */ unsigned char afdata[0]; /* Data for frame */
}; };

Loading…
Cancel
Save