Fix overflow for RNDIS class driver responses when returning the adapter query list...
authorDean Camera <dean@fourwalledcubicle.com>
Sun, 31 Aug 2014 10:14:48 +0000 (20:14 +1000)
committerDean Camera <dean@fourwalledcubicle.com>
Sun, 31 Aug 2014 10:14:48 +0000 (20:14 +1000)
Demos/Device/ClassDriver/RNDISEthernet/Lib/DHCP.c
Demos/Device/ClassDriver/RNDISEthernet/Lib/Webserver.h
Demos/Device/ClassDriver/RNDISEthernet/RNDISEthernet.c
Demos/Device/LowLevel/RNDISEthernet/RNDISEthernet.h
LUFA/DoxygenPages/ChangeLog.txt
LUFA/DoxygenPages/MigrationInformation.txt
LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h
LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c
LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h
Projects/Webserver/USBDeviceMode.c

index a72a6ce..b3b5d69 100644 (file)
@@ -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);
 
index 8307d46..142dc7a 100644 (file)
@@ -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);
index 95d9354..bdb5061 100644 (file)
 
 #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.
index d01b3cb..90fbae3 100644 (file)
@@ -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
 
index 3eab8b0..db10c2a 100644 (file)
   *   - 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
index e87fa16..e2e0f9a 100644 (file)
@@ -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>
index 5c6d3fd..640745e 100644 (file)
                #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
 
index 061f1b2..6ee73c5 100644 (file)
@@ -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:
index 4ba729a..2821d7d 100644 (file)
 
                                        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. */
 
        /* 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)
index b8e41f4..b2c6b39 100644 (file)
@@ -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),
                        },
        };