Fix overflow for RNDIS class driver responses when returning the adapter query list (thanks to Peter Mc Shane).

pull/1469/head
Dean Camera 10 years ago
parent 2db71bc8a4
commit 0e68abcd4f

@ -54,8 +54,8 @@ int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart,
DHCP_Header_t* DHCPHeaderIN = (DHCP_Header_t*)DHCPHeaderInStart;
DHCP_Header_t* DHCPHeaderOUT = (DHCP_Header_t*)DHCPHeaderOutStart;
uint8_t* DHCPOptionsINStart = (uint8_t*)(DHCPHeaderInStart + sizeof(DHCP_Header_t));
uint8_t* DHCPOptionsOUTStart = (uint8_t*)(DHCPHeaderOutStart + sizeof(DHCP_Header_t));
uint8_t* DHCPOptionsINStart = ((uint8_t*)DHCPHeaderInStart + sizeof(DHCP_Header_t));
uint8_t* DHCPOptionsOUTStart = ((uint8_t*)DHCPHeaderOutStart + sizeof(DHCP_Header_t));
DecodeDHCPHeader(DHCPHeaderInStart);

@ -46,7 +46,7 @@
/* Macros: */
/** Maximum size of a HTTP response per transmission */
#define HTTP_REPLY_BLOCK_SIZE 128
#define HTTP_REPLY_BLOCK_SIZE 128
/* Function Prototypes: */
void Webserver_Init(void);

@ -36,6 +36,15 @@
#include "RNDISEthernet.h"
/** Message buffer for RNDIS messages processed by the RNDIS device class driver. */
static uint8_t RNDIS_Message_Buffer[192];
/** Global to store the incoming frame from the host before it is processed by the device. */
static Ethernet_Frame_Info_t FrameIN;
/** Global to store the outgoing frame created in the device before it is sent to the host. */
static Ethernet_Frame_Info_t FrameOUT;
/** LUFA RNDIS Class driver interface configuration and state information. This structure is
* passed to all RNDIS Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another.
@ -65,14 +74,11 @@ USB_ClassInfo_RNDIS_Device_t Ethernet_RNDIS_Interface =
},
.AdapterVendorDescription = "LUFA RNDIS Demo Adapter",
.AdapterMACAddress = {ADAPTER_MAC_ADDRESS},
.MessageBuffer = RNDIS_Message_Buffer,
.MessageBufferLength = sizeof(RNDIS_Message_Buffer),
},
};
/** Global to store the incoming frame from the host before it is processed by the device. */
static Ethernet_Frame_Info_t FrameIN;
/** Global to store the outgoing frame created in the device before it is sent to the host. */
static Ethernet_Frame_Info_t FrameOUT;
/** Main program entry point. This routine contains the overall program flow, including initial
* setup of all components and the main program loop.

@ -58,9 +58,6 @@
#include <LUFA/Platform/Platform.h>
/* Macros: */
/** Notification value to indicate that a frame is ready to be read by the host. */
#define NOTIF_RESPONSE_AVAILABLE 0x01
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
#define LEDMASK_USB_NOTREADY LEDS_LED1

@ -12,6 +12,11 @@
* - Updated the BUILD build system module to add a new COMPILER_PATH optional variable
* - Added Serial_IsSendReady() and Serial_IsSendComplete() functions to the Serial hardware peripheral driver
*
* <b>Changed:</b>
* - Core:
* - The RNDIS device class driver now takes a user-supplied buffer and buffer length for the internal RNDIS
* message management (thanks to Peter Mc Shane)
*
* <b>Fixed:</b>
* - Core:
* - Fixed device class driver pipe configuration routines returning success with a partially constructed instance

@ -11,7 +11,9 @@
* areas relevant to making older projects compatible with the API changes of each new release.
*
* \section Sec_MigrationXXXXXX Migrating from 140302 to XXXXXX
* None
* <b>Device Mode</b>
* - The device mode RNDIS class driver now requires a user-supplied buffer and buffer length to operate, rather
* than allocating this buffer internally.
*
* \section Sec_Migration140302 Migrating from 130901 to 140302
* <b>USB Core</b>

@ -172,9 +172,6 @@
#define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL
//@}
/** Maximum size in bytes of a RNDIS control message which can be sent or received. */
#define RNDIS_MESSAGE_BUFFER_SIZE 128
/** Maximum size in bytes of an Ethernet frame according to the Ethernet standard. */
#define ETHERNET_FRAME_SIZE_MAX 1500

@ -82,7 +82,7 @@ void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDI
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
{
Endpoint_ClearSETUP();
Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, USB_ControlRequest.wLength);
Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->Config.MessageBuffer, USB_ControlRequest.wLength);
Endpoint_ClearIN();
RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo);
@ -92,16 +92,16 @@ void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDI
case RNDIS_REQ_GetEncapsulatedResponse:
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
{
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)RNDISInterfaceInfo->Config.MessageBuffer;
if (!(MessageHeader->MessageLength))
{
RNDISInterfaceInfo->State.RNDISMessageBuffer[0] = 0;
MessageHeader->MessageLength = CPU_TO_LE32(1);
RNDISInterfaceInfo->Config.MessageBuffer[0] = 0;
MessageHeader->MessageLength = CPU_TO_LE32(1);
}
Endpoint_ClearSETUP();
Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, le32_to_cpu(MessageHeader->MessageLength));
Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->Config.MessageBuffer, le32_to_cpu(MessageHeader->MessageLength));
Endpoint_ClearOUT();
MessageHeader->MessageLength = CPU_TO_LE32(0);
@ -119,6 +119,12 @@ bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISIn
RNDISInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK;
RNDISInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT;
if (RNDISInterfaceInfo->Config.MessageBuffer == NULL)
return false;
if (RNDISInterfaceInfo->Config.MessageBufferLength < RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH)
return false;
if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataINEndpoint, 1)))
return false;
@ -162,7 +168,7 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const
/* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of
this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)RNDISInterfaceInfo->Config.MessageBuffer;
switch (le32_to_cpu(MessageHeader->MessageType))
{
@ -170,9 +176,9 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Initialize_Message_t* INITIALIZE_Message =
(RNDIS_Initialize_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
(RNDIS_Initialize_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
RNDIS_Initialize_Complete_t* INITIALIZE_Response =
(RNDIS_Initialize_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
(RNDIS_Initialize_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
INITIALIZE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT);
INITIALIZE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t));
@ -201,13 +207,13 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const
case REMOTE_NDIS_QUERY_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
uint32_t Query_Oid = CPU_TO_LE32(QUERY_Message->Oid);
void* QueryData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
le32_to_cpu(QUERY_Message->InformationBufferOffset)];
void* ResponseData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Query_Complete_t)];
void* QueryData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) +
le32_to_cpu(QUERY_Message->InformationBufferOffset)];
void* ResponseData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Query_Complete_t)];
uint16_t ResponseSize;
QUERY_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT);
@ -234,15 +240,15 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const
case REMOTE_NDIS_SET_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
uint32_t SET_Oid = le32_to_cpu(SET_Message->Oid);
SET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT);
SET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t));
SET_Response->RequestId = SET_Message->RequestId;
void* SetData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +
void* SetData = &RNDISInterfaceInfo->Config.MessageBuffer[sizeof(RNDIS_Message_Header_t) +
le32_to_cpu(SET_Message->InformationBufferOffset)];
SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData,
@ -252,7 +258,7 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const
case REMOTE_NDIS_RESET_MSG:
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
RESET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT);
RESET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t));
@ -264,9 +270,9 @@ void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const
RNDISInterfaceInfo->State.ResponseReady = true;
RNDIS_KeepAlive_Message_t* KEEPALIVE_Message =
(RNDIS_KeepAlive_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
(RNDIS_KeepAlive_Message_t*)RNDISInterfaceInfo->Config.MessageBuffer;
RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response =
(RNDIS_KeepAlive_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer;
(RNDIS_KeepAlive_Complete_t*)RNDISInterfaceInfo->Config.MessageBuffer;
KEEPALIVE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT);
KEEPALIVE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t));
@ -387,7 +393,7 @@ static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RN
*ResponseSize = sizeof(uint32_t);
/* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */
*((uint32_t*)ResponseData) = CPU_TO_LE32(RNDIS_MESSAGE_BUFFER_SIZE + ETHERNET_FRAME_SIZE_MAX);
*((uint32_t*)ResponseData) = CPU_TO_LE32(RNDISInterfaceInfo->Config.MessageBufferLength + ETHERNET_FRAME_SIZE_MAX);
return true;
default:

@ -87,14 +87,15 @@
char* AdapterVendorDescription; /**< String description of the adapter vendor. */
MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter. */
uint8_t* MessageBuffer; /**< Buffer where RNDIS messages can be stored by the internal driver. This
* should be at least 132 bytes in length for minimal functionality. */
uint16_t MessageBufferLength; /**< Length in bytes of the \ref MessageBuffer RNDIS buffer. */
} Config; /**< Config data for the USB class interface within the device. All elements in this section
* <b>must</b> be set or the interface will fail to enumerate and operate correctly.
*/
struct
{
uint8_t RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE]; /**< Buffer to hold RNDIS messages to and from the host,
* managed by the class driver.
*/
bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host. */
uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the \ref RNDIS_States_t enum. */
uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver. */
@ -172,6 +173,9 @@
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define RNDIS_DEVICE_MIN_MESSAGE_BUFFER_LENGTH sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_Query_Complete_t)
/* Function Prototypes: */
#if defined(__INCLUDE_FROM_RNDIS_DEVICE_C)
static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo)

@ -36,6 +36,9 @@
#include "USBDeviceMode.h"
/** Message buffer for RNDIS messages processed by the RNDIS device class driver. */
static uint8_t RNDIS_Message_Buffer[192];
/** LUFA RNDIS Class driver interface configuration and state information. This structure is
* passed to all RNDIS Class driver functions, so that multiple instances of the same class
* within a device can be differentiated from one another.
@ -65,6 +68,8 @@ USB_ClassInfo_RNDIS_Device_t Ethernet_RNDIS_Interface_Device =
},
.AdapterVendorDescription = "LUFA RNDIS Adapter",
.AdapterMACAddress = {{0x02, 0x00, 0x02, 0x00, 0x02, 0x00}},
.MessageBuffer = RNDIS_Message_Buffer,
.MessageBufferLength = sizeof(RNDIS_Message_Buffer),
},
};

Loading…
Cancel
Save