From 4a13a5484ae19974a46d3def668aa888d12b8f13 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Tue, 25 May 2010 06:14:37 +0000 Subject: [PATCH] Fixed RNDISEthernet demos crashing when calculating checksums for Ethernet/TCP packets of more than ~500 bytes due to an overflow in the checksum calculation loop (thanks to Kevin Malec). Removed string Attributes from the Service Discovery Protocol code to minimise the potential points of failure while the base code is being debugged. --- .../ClassDriver/RNDISEthernet/Lib/Ethernet.c | 2 +- .../ClassDriver/RNDISEthernet/Lib/TCP.c | 2 +- .../LowLevel/RNDISEthernet/Lib/Ethernet.c | 2 +- Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c | 2 +- .../Lib/ServiceDiscoveryProtocol.c | 50 ++++--------------- .../Lib/ServiceDiscoveryProtocol.h | 5 -- LUFA/Common/Common.h | 2 +- LUFA/ManPages/ChangeLog.txt | 3 +- 8 files changed, 18 insertions(+), 50 deletions(-) diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c b/Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c index a3a42e22dd..e34f824e93 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/Ethernet.c @@ -120,7 +120,7 @@ uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes) uint16_t* Words = (uint16_t*)Data; uint32_t Checksum = 0; - for (uint8_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++) + for (uint16_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++) Checksum += Words[CurrWord]; while (Checksum & 0xFFFF0000) diff --git a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c index 318085f594..6b62edb13a 100644 --- a/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c +++ b/Demos/Device/ClassDriver/RNDISEthernet/Lib/TCP.c @@ -608,7 +608,7 @@ static uint16_t TCP_Checksum16(void* TCPHeaderOutStart, IP_Address_t SourceAddre Checksum += SwapEndian_16(PROTOCOL_TCP); Checksum += SwapEndian_16(TCPOutSize); - for (uint8_t CurrWord = 0; CurrWord < (TCPOutSize >> 1); CurrWord++) + for (uint16_t CurrWord = 0; CurrWord < (TCPOutSize >> 1); CurrWord++) Checksum += ((uint16_t*)TCPHeaderOutStart)[CurrWord]; if (TCPOutSize & 0x01) diff --git a/Demos/Device/LowLevel/RNDISEthernet/Lib/Ethernet.c b/Demos/Device/LowLevel/RNDISEthernet/Lib/Ethernet.c index 7131ac2b0c..044b0695b1 100644 --- a/Demos/Device/LowLevel/RNDISEthernet/Lib/Ethernet.c +++ b/Demos/Device/LowLevel/RNDISEthernet/Lib/Ethernet.c @@ -125,7 +125,7 @@ uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes) uint16_t* Words = (uint16_t*)Data; uint32_t Checksum = 0; - for (uint8_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++) + for (uint16_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++) Checksum += Words[CurrWord]; while (Checksum & 0xFFFF0000) diff --git a/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c b/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c index 8ec8fca1d6..76031490dc 100644 --- a/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c +++ b/Demos/Device/LowLevel/RNDISEthernet/Lib/TCP.c @@ -605,7 +605,7 @@ static uint16_t TCP_Checksum16(void* TCPHeaderOutStart, IP_Address_t SourceAddre Checksum += SwapEndian_16(PROTOCOL_TCP); Checksum += SwapEndian_16(TCPOutSize); - for (uint8_t CurrWord = 0; CurrWord < (TCPOutSize >> 1); CurrWord++) + for (uint16_t CurrWord = 0; CurrWord < (TCPOutSize >> 1); CurrWord++) Checksum += ((uint16_t*)TCPHeaderOutStart)[CurrWord]; if (TCPOutSize & 0x01) diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.c b/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.c index cb858d68cf..accbee5ab7 100644 --- a/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.c +++ b/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.c @@ -31,40 +31,18 @@ #define INCLUDE_FROM_SERVICEDISCOVERYPROTOCOL_C #include "ServiceDiscoveryProtocol.h" -/** Service Discovery Protocol attribute, indicationg the service's name. */ -const struct -{ - uint8_t Header; - uint8_t Length; - uint8_t Data[]; -} PROGMEM SDP_Attribute_Name = {(SDP_DATATYPE_String | SDP_DATASIZE_Variable8Bit), sizeof("SDP"), "SDP"}; - -/** Service Discovery Protocol attribute, indicationg the service's description. */ -const struct -{ - uint8_t Header; - uint8_t Length; - uint8_t Data[]; -} PROGMEM SDP_Attribute_Description = {(SDP_DATATYPE_String | SDP_DATASIZE_Variable8Bit), sizeof("BT Service Discovery"), "BT Service Discovery"}; - -/** Service Discovery Protocol attribute, indicationg the service's availability. */ +/** Service Discovery Protocol attribute, indicating the service's availability. */ const struct { uint8_t Header; uint8_t Data; } PROGMEM SDP_Attribute_Availability = {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_8Bit), 0xFF}; -const struct -{ - uint8_t Header; - uint16_t Data; -} PROGMEM SDP_Attribute_LanguageOffset = {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_16Bit), SDP_ATTRIBUTE_LANGOFFSET}; - const struct { uint8_t Header; uint32_t Data; -} PROGMEM SDP_Attribute_ServiceHandle = {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_32Bit), 0x00000001}; +} PROGMEM SDP_Attribute_ServiceHandle = {(SDP_DATATYPE_UnsignedInt | SDP_DATASIZE_32Bit), 0x00010000}; const struct { @@ -102,9 +80,6 @@ const ServiceAttributeTable_t SDP_Attribute_Table[] PROGMEM = {.AttributeID = SDP_ATTRIBUTE_ID_SERVICERECORDHANDLE, .Data = &SDP_Attribute_ServiceHandle }, {.AttributeID = SDP_ATTRIBUTE_ID_SERVICECLASSIDS, .Data = &SDP_Attribute_ServiceClassIDs }, {.AttributeID = SDP_ATTRIBUTE_ID_VERSION, .Data = &SDP_Attribute_Version }, - {.AttributeID = SDP_ATTRIBUTE_ID_LANGIDOFFSET, .Data = &SDP_Attribute_LanguageOffset }, - {.AttributeID = SDP_ATTRIBUTE_ID_NAME, .Data = &SDP_Attribute_Name }, - {.AttributeID = SDP_ATTRIBUTE_ID_DESCRIPTION, .Data = &SDP_Attribute_Description }, SERVICE_ATTRIBUTE_TABLE_TERMINATOR }; @@ -118,12 +93,6 @@ const ServiceTable_t SDP_Services_Table[] PROGMEM = .UUID = {BASE_96BIT_UUID, 0x00, 0x00, 0x00, 0x01}, .AttributeTable = SDP_Attribute_Table, }, -#if 0 - { // 128-bit UUID for the RFCOMM service - .UUID = {BASE_96BIT_UUID, 0x03, 0x00, 0x00, 0x00}, - .AttributeTable = RFCOMM_Attribute_Table, - }, -#endif }; /** Base UUID value common to all standardized Bluetooth services */ @@ -220,7 +189,7 @@ static void SDP_ProcessServiceSearchAttribute(const SDP_PDUHeader_t* const SDPHe if (MaxAttributeSize > sizeof(ResponsePacket.ResponseData)) MaxAttributeSize = sizeof(ResponsePacket.ResponseData); - /* Add the outer Data Element Sequence header for the retrieved Attributes */ + /* Add the outer Data Element Sequence header for all of the retrieved Attributes */ uint16_t* TotalResponseSize = SDP_AddDataElementHeader16(&CurrResponsePos, SDP_DATATYPE_Sequence); /* Search through the list of UUIDs one at a time looking for matching search Attributes */ @@ -263,9 +232,12 @@ static void SDP_ProcessServiceSearchAttribute(const SDP_PDUHeader_t* const SDPHe *TotalResponseSize += 3 + *CurrentUUIDResponseSize; } } + + /* Continuation state - always zero */ + *((uint8_t*)CurrResponsePos) = 0; - /* Set the total response list size to the size of the outer container plus its header size */ - ResponsePacket.AttributeListByteCount = 3 + *TotalResponseSize; + /* Set the total response list size to the size of the outer container plus its header size and continuation state */ + ResponsePacket.AttributeListByteCount = 4 + *TotalResponseSize; /* Fill in the response packet's header */ ResponsePacket.SDPHeader.PDU = SDP_PDU_SERVICESEARCHATTRIBUTERESPONSE; @@ -367,11 +339,11 @@ static ServiceAttributeTable_t* SDP_GetAttributeTable(const uint8_t* const UUID) while (ClassUUIDListSize) { /* Current Service UUID's Class UUID list has a matching entry, return the Attribute table */ - if (!(memcmp_P(UUID, (ClassUUIDs + 1), UUID_SIZE_BYTES))) + if (!(memcmp_P(UUID, &((ClassUUID_t*)ClassUUIDs)->UUID, UUID_SIZE_BYTES))) return CurrAttributeTable; - ClassUUIDs += sizeof(uint8_t) + UUID_SIZE_BYTES; - ClassUUIDListSize -= sizeof(uint8_t) + UUID_SIZE_BYTES; + ClassUUIDListSize -= sizeof(ClassUUID_t); + ClassUUIDs += sizeof(ClassUUID_t); } } diff --git a/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.h b/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.h index a9ed417419..9103dce639 100644 --- a/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.h +++ b/Demos/Host/Incomplete/BluetoothHost/Lib/ServiceDiscoveryProtocol.h @@ -59,12 +59,7 @@ #define SDP_ATTRIBUTE_ID_LANGIDOFFSET 0x0006 #define SDP_ATTRIBUTE_ID_AVAILABILITY 0x0008 #define SDP_ATTRIBUTE_ID_VERSION 0x0200 - #define SDP_ATTRIBUTE_ID_NAME (0x0000 + SDP_ATTRIBUTE_LANGOFFSET) - #define SDP_ATTRIBUTE_ID_DESCRIPTION (0x0001 + SDP_ATTRIBUTE_LANGOFFSET) - /** Attribute ID offset for localised language string attributes. */ - #define SDP_ATTRIBUTE_LANGOFFSET 0x0100 - /** Size of a full 128 bit UUID, in bytes. */ #define UUID_SIZE_BYTES 16 diff --git a/LUFA/Common/Common.h b/LUFA/Common/Common.h index 68419ce2d9..86b84cc2a3 100644 --- a/LUFA/Common/Common.h +++ b/LUFA/Common/Common.h @@ -167,7 +167,7 @@ static inline void SwapEndian_n(void* Data, uint8_t Bytes); static inline void SwapEndian_n(void* Data, uint8_t Bytes) { - uint8_t* CurrDataPos = Data; + uint8_t* CurrDataPos = (uint8_t*)Data; while (Bytes) { diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 0e51f21ad7..f47ae06e15 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -18,6 +18,8 @@ * the last page of FLASH (thanks to Gerard Sexton) * - Fixed AVRISP project not sending a full erase-and-write EEPROM command to XMEGA targets when writing to the EEPROM * instead of the split write-only command (thanks to Tim Margush) + * - Fixed RNDISEthernet demos crashing when calculating checksums for Ethernet/TCP packets of more than ~500 bytes due to + * an overflow in the checksum calculation loop (thanks to Kevin Malec) * * \section Sec_ChangeLog100513 Version 100513 * New: @@ -92,7 +94,6 @@ * HID_HOST_BOOT_PROTOCOL_ONLY compile time option is set * - Fixed INTERRUPT_CONTROL_ENDPOINT compile time option preventing other interrupts from occuring while the control endpoint * request is being processed, causing possible lockups if a USB interrupt occurs during a transfer - * - Fixed TeensyHID bootloader not working on some USB AVR models with the official TeensyLoader GUI application * - Remove incorrect Abstract Call Management class specific descriptor from the CDC demos, bootloaders and projects * * \section Sec_ChangeLog100219 Version 100219