Răsfoiți Sursa

sanity checks

eihrul 13 ani în urmă
părinte
comite
78222dc79e
4 a modificat fișierele cu 42 adăugiri și 17 ștergeri
  1. 3 1
      include/enet/protocol.h
  2. 5 1
      packet.c
  3. 9 4
      peer.c
  4. 25 11
      protocol.c

+ 3 - 1
include/enet/protocol.h

@@ -16,7 +16,9 @@ enum
    ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE     = 32768,
    ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT   = 1,
    ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT   = 255,
-   ENET_PROTOCOL_MAXIMUM_PEER_ID         = 0xFFF
+   ENET_PROTOCOL_MAXIMUM_PEER_ID         = 0xFFF,
+   ENET_PROTOCOL_MAXIMUM_PACKET_SIZE     = 1024 * 1024 * 1024,
+   ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT  = 1024 * 1024
 };
 
 typedef enum _ENetProtocolCommand

+ 5 - 1
packet.c

@@ -26,6 +26,9 @@ enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
     if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
       packet -> data = (enet_uint8 *) data;
     else
+    if (dataLength <= 0)
+      packet -> data = NULL;
+    else
     {
        packet -> data = (enet_uint8 *) enet_malloc (dataLength);
        if (packet -> data == NULL)
@@ -54,7 +57,8 @@ enet_packet_destroy (ENetPacket * packet)
 {
     if (packet -> freeCallback != NULL)
       (* packet -> freeCallback) (packet);
-    if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
+    if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE) &&
+        packet -> data != NULL)
       enet_free (packet -> data);
     enet_free (packet);
 }

+ 9 - 4
peer.c

@@ -104,7 +104,8 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
    size_t fragmentLength;
 
    if (peer -> state != ENET_PEER_STATE_CONNECTED ||
-       channelID >= peer -> channelCount)
+       channelID >= peer -> channelCount ||
+       packet -> dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE)
      return -1;
 
    fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
@@ -113,7 +114,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
 
    if (packet -> dataLength > fragmentLength)
    {
-      enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
+      enet_uint32 fragmentCount = (packet -> dataLength + fragmentLength - 1) / fragmentLength,
              fragmentNumber,
              fragmentOffset;
       enet_uint8 commandNumber;
@@ -121,6 +122,9 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
       ENetList fragments;
       ENetOutgoingCommand * fragment;
 
+      if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT)
+        return -1;
+
       if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT)) == ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT &&
           channel -> outgoingUnreliableSequenceNumber < 0xFFFF)
       {
@@ -164,7 +168,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
          fragment -> command.header.channelID = channelID;
          fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber;
          fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
-         fragment -> command.sendFragment.fragmentCount = fragmentCount;
+         fragment -> command.sendFragment.fragmentCount = ENET_HOST_TO_NET_32 (fragmentCount);
          fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
          fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
          fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
@@ -832,7 +836,8 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command,
     
     if (fragmentCount > 0)
     { 
-       incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
+       if (fragmentCount <= ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT)
+         incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
        if (incomingCommand -> fragments == NULL)
        {
           enet_free (incomingCommand);

+ 25 - 11
protocol.c

@@ -406,7 +406,9 @@ enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENet
 
     dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength);
     * currentData += dataLength;
-    if (* currentData > & host -> receivedData [host -> receivedDataLength])
+    if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+        * currentData < host -> receivedData ||
+        * currentData > & host -> receivedData [host -> receivedDataLength])
       return -1;
 
     packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable),
@@ -432,7 +434,9 @@ enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const E
 
     dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength);
     * currentData += dataLength;
-    if (* currentData > & host -> receivedData [host -> receivedDataLength])
+    if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+        * currentData < host -> receivedData ||
+        * currentData > & host -> receivedData [host -> receivedDataLength])
       return -1; 
 
     unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup);
@@ -480,7 +484,9 @@ enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const EN
 
     dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength);
     * currentData += dataLength;
-    if (* currentData > & host -> receivedData [host -> receivedDataLength])
+    if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+        * currentData < host -> receivedData ||
+        * currentData > & host -> receivedData [host -> receivedDataLength])
       return -1;
 
     packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable),
@@ -513,7 +519,9 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
 
     fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
     * currentData += fragmentLength;
-    if (* currentData > & host -> receivedData [host -> receivedDataLength])
+    if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+        * currentData < host -> receivedData ||
+        * currentData > & host -> receivedData [host -> receivedDataLength])
       return -1;
 
     channel = & peer -> channels [command -> header.channelID];
@@ -532,9 +540,11 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet
     fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
     totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
     
-    if (fragmentOffset >= totalLength ||
-        fragmentOffset + fragmentLength > totalLength ||
-        fragmentNumber >= fragmentCount)
+    if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
+        fragmentNumber >= fragmentCount ||
+        totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+        fragmentOffset >= totalLength ||
+        fragmentLength > totalLength - fragmentOffset)
       return -1;
  
     for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
@@ -622,7 +632,9 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
 
     fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength);
     * currentData += fragmentLength;
-    if (* currentData > & host -> receivedData [host -> receivedDataLength])
+    if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+        * currentData < host -> receivedData ||
+        * currentData > & host -> receivedData [host -> receivedDataLength])
       return -1;
 
     channel = & peer -> channels [command -> header.channelID];
@@ -647,9 +659,11 @@ enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer,
     fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset);
     totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength);
 
-    if (fragmentOffset >= totalLength ||
-        fragmentOffset + fragmentLength > totalLength ||
-        fragmentNumber >= fragmentCount)
+    if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT ||
+        fragmentNumber >= fragmentCount ||
+        totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE ||
+        fragmentOffset >= totalLength ||
+        fragmentLength > totalLength - fragmentOffset)
       return -1;
 
     for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));