提交 8a98baa6 authored 作者: Stefan Knoblich's avatar Stefan Knoblich 提交者: Ken Rice

ftmod_isdn: Avoid stack smashing buffer overflow in isdn_tones_run().

The len variable can, in certain situations (large burst of incoming non-SLIN audio),
exceed the size of the on-stack frame buffer, which causes ftdm_buffer_read_loop() to
overwrite the dt_buffer pointer.

Use ftdm_min() to make sure len (after conversion to SLIN units) isn't larger
than the frame buffer size.

Also adds are couple more code comments.
Signed-off-by: 's avatarStefan Knoblich <stkn@openisdn.net>
上级 d1db17b4
......@@ -1936,6 +1936,11 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
continue;
}
/*
* Teletone operates on SLIN data (2 bytes per sample).
* Convert the length of non-SLIN codecs, so we read
* the right amount of samples from the buffer.
*/
if (chan->effective_codec != FTDM_CODEC_SLIN) {
len *= 2;
}
......@@ -1943,6 +1948,12 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
/* seek to current offset */
ftdm_buffer_seek(dt_buffer, data->offset);
/*
* ftdm_channel_read() can read up to sizeof(frame) bytes
* (in certain situations). Avoid overflowing the stack (and smashing dt_buffer)
* if the codec is not slin and we had to double the length.
*/
len = ftdm_min(len, sizeof(frame));
rlen = ftdm_buffer_read_loop(dt_buffer, frame, len);
if (chan->effective_codec != FTDM_CODEC_SLIN) {
......@@ -1954,6 +1965,12 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
codec_func = fio_slin2alaw;
}
/*
* Convert SLIN to native format (a-law/u-law),
* input size is 2 bytes per sample, output size
* (after conversion) is one byte per sample
* (= max. half the input size).
*/
if (codec_func) {
status = codec_func(frame, sizeof(frame), &rlen);
} else {
......@@ -1968,11 +1985,12 @@ static void *ftdm_isdn_tones_run(ftdm_thread_t *me, void *obj)
* of data actually written to channel.
*/
if (chan->effective_codec != FTDM_CODEC_SLIN) {
data->offset += rlen << 1; /* teletone buffer is slin (= len * 2) */
data->offset += rlen << 1; /* Teletone buffer is in SLIN (= rlen * 2) */
} else {
data->offset += rlen;
}
/* Limit offset to [0..Rate(Samples/s)-1] in SLIN (2 bytes per sample) units. */
data->offset %= (ts.rate << 1);
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论