Enable check on received length to prevent buffer overflow. Thank you Cooja!

This commit is contained in:
David Kopf 2012-05-28 13:02:23 -04:00
parent e62f2c3977
commit e9a55cc222

View file

@ -575,111 +575,96 @@ hal_subregister_write(uint8_t address, uint8_t mask, uint8_t position,
} }
#endif /* defined(__AVR_ATmega128RFA1__) */ #endif /* defined(__AVR_ATmega128RFA1__) */
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/** \brief This function will upload a frame from the radio transceiver's frame /** \brief Transfer a frame from the radio transceiver to a RAM buffer
* buffer.
* *
* If the frame currently available in the radio transceiver's frame buffer
* is out of the defined bounds. Then the frame length, lqi value and crc
* be set to zero. This is done to indicate an error.
* This version is optimized for use with contiki RF230BB driver. * This version is optimized for use with contiki RF230BB driver.
* The callback routine and CRC are left out for speed in reading the rx buffer. * The callback routine and CRC are left out for speed in reading the rx buffer.
* Any delays here can lead to overwrites by the next packet! * Any delays here can lead to overwrites by the next packet!
* *
* If the frame length is out of the defined bounds, the length, lqi and crc
* are set to zero.
*
* \param rx_frame Pointer to the data structure where the frame is stored. * \param rx_frame Pointer to the data structure where the frame is stored.
* \param rx_callback Pointer to callback function for receiving one byte at a time.
*/ */
void void
//hal_frame_read(hal_rx_frame_t *rx_frame, rx_callback_t rx_callback)
hal_frame_read(hal_rx_frame_t *rx_frame) hal_frame_read(hal_rx_frame_t *rx_frame)
{ {
#if defined(__AVR_ATmega128RFA1__) #if defined(__AVR_ATmega128RFA1__)
uint8_t frame_length,*rx_data,*rx_buffer; uint8_t frame_length,*rx_data,*rx_buffer;
rx_data = (rx_frame->data); /* Get length from the TXT_RX_LENGTH register, not including LQI
frame_length = TST_RX_LENGTH; //frame length, not including lqi? * Bypassing the length check can result in overrun if buffer is < 256 bytes.
rx_frame->length = frame_length; */
rx_buffer=(uint8_t *)0x180; //start of fifo in i/o space frame_length = TST_RX_LENGTH;
if ( 0 || ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH))) {
rx_frame->length = frame_length;
do{ /* Start of buffer in I/O space, pointer to RAM buffer */
*rx_data++ = _SFR_MEM8(rx_buffer++); rx_buffer=(uint8_t *)0x180;
rx_data = (rx_frame->data);
} while (--frame_length > 0); do{
*rx_data++ = _SFR_MEM8(rx_buffer++);
} while (--frame_length > 0);
/*Read LQI value for this frame.*/ /*Read LQI value for this frame.*/
rx_frame->lqi = *rx_buffer; rx_frame->lqi = *rx_buffer;
if (1) {
#else /* defined(__AVR_ATmega128RFA1__) */ #else /* defined(__AVR_ATmega128RFA1__) */
uint8_t *rx_data; uint8_t *rx_data;
/* check that we have either valid frame pointer or callback pointer */
// if (!rx_frame && !rx_callback)
// return;
HAL_SPI_TRANSFER_OPEN();
/*Send frame read (long mode) command.*/ /*Send frame read (long mode) command.*/
HAL_SPI_TRANSFER_OPEN();
HAL_SPI_TRANSFER(0x20); HAL_SPI_TRANSFER(0x20);
/*Read frame length. This includes the checksum. */ /*Read frame length. This includes the checksum. */
uint8_t frame_length = HAL_SPI_TRANSFER(0); uint8_t frame_length = HAL_SPI_TRANSFER(0);
/*Check for correct frame length.*/ /*Check for correct frame length. Bypassing this test can result in a buffer overrun! */
// if ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH)){ if ( 0 || ((frame_length >= HAL_MIN_FRAME_LENGTH) && (frame_length <= HAL_MAX_FRAME_LENGTH))) {
if (1) {
// uint16_t crc = 0; rx_data = (rx_frame->data);
// if (rx_frame){ rx_frame->length = frame_length;
rx_data = (rx_frame->data);
rx_frame->length = frame_length; /*Transfer frame buffer to RAM buffer */
// } else {
// rx_callback(frame_length);
// }
/*Upload frame buffer to data pointer */
HAL_SPI_TRANSFER_WRITE(0); HAL_SPI_TRANSFER_WRITE(0);
HAL_SPI_TRANSFER_WAIT(); HAL_SPI_TRANSFER_WAIT();
do{ do{
*rx_data++ = HAL_SPI_TRANSFER_READ(); *rx_data++ = HAL_SPI_TRANSFER_READ();
HAL_SPI_TRANSFER_WRITE(0); HAL_SPI_TRANSFER_WRITE(0);
// if (rx_frame){ /* CRC was checked in hardware, but redoing the checksum here ensures the rx buffer
// *rx_data++ = tempData; * is not being overwritten by the next packet. Since that lengthy computation makes
// } else { * such overwrites more likely, we skip it and hope for the best.
// rx_callback(tempData); * Without the check a full buffer is read in 320us at 2x spi clocking.
// } * The 802.15.4 standard requires 640us after a greater than 18 byte frame.
/* RF230 does crc in hardware, doing the checksum here ensures the rx buffer has not been overwritten by the next packet */ * With a low interrupt latency overwrites should never occur.
/* Since doing the checksum makes such overwrites more probable, we skip it and hope for the best. */ */
/* A full buffer should be read in 320us at 2x spi clocking, so with a low interrupt latency overwrites should not occur */ // crc = _crc_ccitt_update(crc, tempData);
// crc = _crc_ccitt_update(crc, tempData);
HAL_SPI_TRANSFER_WAIT(); HAL_SPI_TRANSFER_WAIT();
} while (--frame_length > 0); } while (--frame_length > 0);
/*Read LQI value for this frame.*/ /*Read LQI value for this frame.*/
// if (rx_frame){
rx_frame->lqi = HAL_SPI_TRANSFER_READ(); rx_frame->lqi = HAL_SPI_TRANSFER_READ();
// } else {
// rx_callback(HAL_SPI_TRANSFER_READ());
// }
#endif /* defined(__AVR_ATmega128RFA1__) */ #endif /* defined(__AVR_ATmega128RFA1__) */
/*Check calculated crc, and set crc field in hal_rx_frame_t accordingly.*/ /* If crc was calculated set crc field in hal_rx_frame_t accordingly.
// if (rx_frame){ * Else show the crc has passed the hardware check.
rx_frame->crc = 1; */
// } else { rx_frame->crc = true;
// rx_callback(crc != 0);
// }
} else { } else {
// if (rx_frame){ /* Length test failed */
rx_frame->length = 0; rx_frame->length = 0;
rx_frame->lqi = 0; rx_frame->lqi = 0;
rx_frame->crc = false; rx_frame->crc = false;
// }
} }
HAL_SPI_TRANSFER_CLOSE(); HAL_SPI_TRANSFER_CLOSE();