Fix overflow for RNDIS class driver responses when returning the adapter query list (thanks to Peter Mc Shane).
This commit is contained in:
		
							parent
							
								
									2db71bc8a4
								
							
						
					
					
						commit
						0e68abcd4f
					
				
					 10 changed files with 60 additions and 38 deletions
				
			
		| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue