From 78222dc79e720686028f59bdc8b29b10dbc18cfa Mon Sep 17 00:00:00 2001 From: eihrul Date: Fri, 6 Jan 2012 15:11:04 +0000 Subject: [PATCH] sanity checks --- include/enet/protocol.h | 4 +++- packet.c | 6 +++++- peer.c | 13 +++++++++---- protocol.c | 36 +++++++++++++++++++++++++----------- 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/include/enet/protocol.h b/include/enet/protocol.h index faef917..f8a27d8 100644 --- a/include/enet/protocol.h +++ b/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 diff --git a/packet.c b/packet.c index 2fc9a10..fd59b14 100644 --- a/packet.c +++ b/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); } diff --git a/peer.c b/peer.c index 44b0bc5..38839b1 100644 --- a/peer.c +++ b/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); diff --git a/protocol.c b/protocol.c index 2e111a8..6d4618c 100644 --- a/protocol.c +++ b/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));