mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-25 17:28:50 -05:00
libfreedv: fixed possible out of bounds condition in freedv_data_channel_rx_frame
This commit is contained in:
parent
4a0c4f3941
commit
26b8751d61
@ -96,7 +96,7 @@ struct FDMDV * fdmdv_create(int Nc)
|
|||||||
assert(f->rx_test_bits_mem != NULL);
|
assert(f->rx_test_bits_mem != NULL);
|
||||||
for(i=0; i<f->ntest_bits; i++)
|
for(i=0; i<f->ntest_bits; i++)
|
||||||
f->rx_test_bits_mem[i] = 0;
|
f->rx_test_bits_mem[i] = 0;
|
||||||
assert((sizeof(test_bits)/sizeof(int)) >= f->ntest_bits);
|
assert((sizeof(test_bits)/sizeof(int)) >= (std::size_t) f->ntest_bits);
|
||||||
|
|
||||||
f->old_qpsk_mapping = 0;
|
f->old_qpsk_mapping = 0;
|
||||||
|
|
||||||
|
@ -148,6 +148,7 @@ void freedv_data_set_cb_tx(struct freedv_data_channel *fdc, freedv_data_callback
|
|||||||
void freedv_data_channel_rx_frame(struct freedv_data_channel *fdc, unsigned char *data, std::size_t size, int from_bit, int bcast_bit, int crc_bit, int end_bits)
|
void freedv_data_channel_rx_frame(struct freedv_data_channel *fdc, unsigned char *data, std::size_t size, int from_bit, int bcast_bit, int crc_bit, int end_bits)
|
||||||
{
|
{
|
||||||
int copy_bits;
|
int copy_bits;
|
||||||
|
|
||||||
if (end_bits) {
|
if (end_bits) {
|
||||||
copy_bits = end_bits;
|
copy_bits = end_bits;
|
||||||
} else {
|
} else {
|
||||||
@ -155,44 +156,64 @@ void freedv_data_channel_rx_frame(struct freedv_data_channel *fdc, unsigned char
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* New packet? */
|
/* New packet? */
|
||||||
if (fdc->packet_rx_cnt == 0) {
|
if (fdc->packet_rx_cnt == 0)
|
||||||
|
{
|
||||||
/* Does the packet have a compressed from field? */
|
/* Does the packet have a compressed from field? */
|
||||||
if (from_bit) {
|
if (from_bit) {
|
||||||
/* Compressed from: take the previously received header */
|
/* Compressed from: take the previously received header */
|
||||||
memcpy(fdc->packet_rx + fdc->packet_rx_cnt, fdc->rx_header, 6);
|
memcpy(fdc->packet_rx + fdc->packet_rx_cnt, fdc->rx_header, 6);
|
||||||
fdc->packet_rx_cnt += 6;
|
fdc->packet_rx_cnt += 6;
|
||||||
}
|
}
|
||||||
if (bcast_bit) {
|
|
||||||
if (!from_bit) {
|
if (bcast_bit)
|
||||||
|
{
|
||||||
|
if (!from_bit)
|
||||||
|
{
|
||||||
/* Copy from header and modify size and end_bits accordingly */
|
/* Copy from header and modify size and end_bits accordingly */
|
||||||
memcpy(fdc->packet_rx + fdc->packet_rx_cnt, data, 6);
|
memcpy(fdc->packet_rx + fdc->packet_rx_cnt, data, 6);
|
||||||
fdc->packet_rx_cnt += 6;
|
fdc->packet_rx_cnt += 6;
|
||||||
copy_bits -= 6;
|
copy_bits -= 6;
|
||||||
if (copy_bits < 0)
|
|
||||||
|
if (copy_bits < 0) {
|
||||||
copy_bits = 0;
|
copy_bits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
data += 6;
|
data += 6;
|
||||||
}
|
}
|
||||||
/* Compressed to: fill in broadcast address */
|
/* Compressed to: fill in broadcast address */
|
||||||
memcpy(fdc->packet_rx + fdc->packet_rx_cnt, fdc_header_bcast, sizeof(fdc_header_bcast));
|
memcpy(fdc->packet_rx + fdc->packet_rx_cnt, fdc_header_bcast, sizeof(fdc_header_bcast));
|
||||||
fdc->packet_rx_cnt += 6;
|
fdc->packet_rx_cnt += 6;
|
||||||
}
|
}
|
||||||
if (crc_bit) {
|
|
||||||
|
if (crc_bit)
|
||||||
|
{
|
||||||
unsigned char calc_crc = fdc_crc4(data, size);
|
unsigned char calc_crc = fdc_crc4(data, size);
|
||||||
if (calc_crc == end_bits) {
|
|
||||||
|
if (calc_crc == end_bits)
|
||||||
|
{
|
||||||
/* It is a single header field, remember it for later */
|
/* It is a single header field, remember it for later */
|
||||||
memcpy(fdc->packet_rx + 6, data, 6);
|
memcpy(fdc->packet_rx + 6, data, 6);
|
||||||
memcpy(fdc->packet_rx, fdc_header_bcast, 6);
|
memcpy(fdc->packet_rx, fdc_header_bcast, 6);
|
||||||
|
|
||||||
if (fdc->cb_rx) {
|
if (fdc->cb_rx) {
|
||||||
fdc->cb_rx(fdc->cb_rx_state, fdc->packet_rx, 12);
|
fdc->cb_rx(fdc->cb_rx_state, fdc->packet_rx, 12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fdc->packet_rx_cnt = 0;
|
fdc->packet_rx_cnt = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fdc->packet_rx_cnt + copy_bits >= FREEDV_DATA_CHANNEL_PACKET_MAX) {
|
if (fdc->packet_rx_cnt + copy_bits >= FREEDV_DATA_CHANNEL_PACKET_MAX)
|
||||||
/* Something went wrong... this can not be a real packet */
|
{
|
||||||
|
// Something went wrong... this can not be a real packet
|
||||||
|
fdc->packet_rx_cnt = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (fdc->packet_rx_cnt < 0)
|
||||||
|
{
|
||||||
|
// This is wrong too...
|
||||||
fdc->packet_rx_cnt = 0;
|
fdc->packet_rx_cnt = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -200,31 +221,37 @@ void freedv_data_channel_rx_frame(struct freedv_data_channel *fdc, unsigned char
|
|||||||
memcpy(fdc->packet_rx + fdc->packet_rx_cnt, data, copy_bits);
|
memcpy(fdc->packet_rx + fdc->packet_rx_cnt, data, copy_bits);
|
||||||
fdc->packet_rx_cnt += copy_bits;
|
fdc->packet_rx_cnt += copy_bits;
|
||||||
|
|
||||||
if (end_bits != 0 && fdc->packet_rx_cnt >= 2) {
|
if (end_bits != 0 && fdc->packet_rx_cnt >= 2)
|
||||||
|
{
|
||||||
unsigned short calc_crc = fdc_crc(fdc->packet_rx, fdc->packet_rx_cnt - 2);
|
unsigned short calc_crc = fdc_crc(fdc->packet_rx, fdc->packet_rx_cnt - 2);
|
||||||
unsigned short rx_crc;
|
unsigned short rx_crc;
|
||||||
rx_crc = fdc->packet_rx[fdc->packet_rx_cnt - 1] << 8;
|
rx_crc = fdc->packet_rx[fdc->packet_rx_cnt - 1] << 8;
|
||||||
rx_crc |= fdc->packet_rx[fdc->packet_rx_cnt - 2];
|
rx_crc |= fdc->packet_rx[fdc->packet_rx_cnt - 2];
|
||||||
|
|
||||||
if (rx_crc == calc_crc) {
|
if (rx_crc == calc_crc)
|
||||||
|
{
|
||||||
if ((std::size_t) fdc->packet_rx_cnt == size) {
|
if ((std::size_t) fdc->packet_rx_cnt == size) {
|
||||||
/* It is a single header field, remember it for later */
|
/* It is a single header field, remember it for later */
|
||||||
memcpy(fdc->rx_header, fdc->packet_rx, 6);
|
memcpy(fdc->rx_header, fdc->packet_rx, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* callback */
|
/* callback */
|
||||||
if (fdc->cb_rx) {
|
if (fdc->cb_rx)
|
||||||
|
{
|
||||||
unsigned char tmp[6];
|
unsigned char tmp[6];
|
||||||
memcpy(tmp, fdc->packet_rx, 6);
|
memcpy(tmp, fdc->packet_rx, 6);
|
||||||
memcpy(fdc->packet_rx, fdc->packet_rx + 6, 6);
|
memcpy(fdc->packet_rx, fdc->packet_rx + 6, 6);
|
||||||
memcpy(fdc->packet_rx + 6, tmp, 6);
|
memcpy(fdc->packet_rx + 6, tmp, 6);
|
||||||
|
|
||||||
std::size_t size = fdc->packet_rx_cnt - 2;
|
std::size_t size = fdc->packet_rx_cnt - 2;
|
||||||
if (size < 12)
|
|
||||||
|
if (size < 12) {
|
||||||
size = 12;
|
size = 12;
|
||||||
|
}
|
||||||
|
|
||||||
fdc->cb_rx(fdc->cb_rx_state, fdc->packet_rx, size);
|
fdc->cb_rx(fdc->cb_rx_state, fdc->packet_rx, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fdc->packet_rx_cnt = 0;
|
fdc->packet_rx_cnt = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user