Browse Source

Fix unaligned reads and writes of the checksum (fixes #237) (#238)

Co-authored-by: Arvid Norlander <[email protected]>
Arvid Norlander 1 year ago
parent
commit
c44b7d0f7f
1 changed files with 11 additions and 5 deletions
  1. 11 5
      protocol.c

+ 11 - 5
protocol.c

@@ -1072,11 +1072,14 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
 
     if (host -> checksum != NULL)
     {
-        enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)],
-                    desiredChecksum = * checksum;
+        enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)];
+        enet_uint32 desiredChecksum, newChecksum;
         ENetBuffer buffer;
+        /* Checksum may be an unaligned pointer, use memcpy to avoid undefined behaviour. */
+        memcpy (& desiredChecksum, checksum, sizeof (enet_uint32));
 
-        * checksum = peer != NULL ? peer -> connectID : 0;
+        newChecksum = peer != NULL ? peer -> connectID : 0;
+        memcpy (checksum, & newChecksum, sizeof (enet_uint32));
 
         buffer.data = host -> receivedData;
         buffer.dataLength = host -> receivedDataLength;
@@ -1704,9 +1707,12 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch
         if (host -> checksum != NULL)
         {
             enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength];
-            * checksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0;
+            enet_uint32 newChecksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0;
+            /* Checksum may be unaligned, use memcpy to avoid undefined behaviour. */
+            memcpy(checksum, & newChecksum, sizeof (enet_uint32));
             host -> buffers -> dataLength += sizeof (enet_uint32);
-            * checksum = host -> checksum (host -> buffers, host -> bufferCount);
+            newChecksum = host -> checksum (host -> buffers, host -> bufferCount);
+            memcpy(checksum, & newChecksum, sizeof (enet_uint32));
         }
 
         if (shouldCompress > 0)