@@ -472,7 +472,12 @@ impl Handshake<SentVersion> {
472472 fn split_garbage < ' b > ( & self , buffer : & ' b [ u8 ] ) -> Result < ( & ' b [ u8 ] , & ' b [ u8 ] ) , Error > {
473473 let terminator = & self . state . remote_garbage_terminator ;
474474
475- if let Some ( index) = buffer
475+ // Only search up to the maximum amount of garbage bytes
476+ // allowed in the spec to avoid a DOS vector.
477+ if let Some ( index) = buffer[ ..core:: cmp:: min (
478+ buffer. len ( ) ,
479+ MAX_NUM_GARBAGE_BYTES + NUM_GARBAGE_TERMINTOR_BYTES ,
480+ ) ]
476481 . windows ( terminator. len ( ) )
477482 . position ( |window| window == terminator)
478483 {
@@ -846,32 +851,40 @@ mod tests {
846851
847852 // Test split_garbage error conditions.
848853 //
849- // 1. NoGarbageTerminator - when buffer exceeds max size without finding terminator
850- // 2. CiphertextTooSmall - when buffer is too short to possibly contain terminator
854+ // 1. NoGarbageTerminator - Buffer exceeds max size without finding terminator.
855+ // 2. CiphertextTooSmall - Buffer is too short to possibly contain terminator.i
851856 #[ test]
852857 fn test_handshake_split_garbage ( ) {
853- // Create a handshake and bring it to the SentVersion state to test split_garbage
858+ // Create a handshake and bring it to the SentVersion state to test split_garbage.
854859 let handshake = Handshake :: < Initialized > :: new ( Network :: Bitcoin , Role :: Initiator ) . unwrap ( ) ;
855860 let mut buffer = vec ! [ 0u8 ; NUM_ELLIGATOR_SWIFT_BYTES ] ;
856861 let handshake = handshake. send_key ( None , & mut buffer) . unwrap ( ) ;
857862
858- // Create a fake peer key to receive
863+ // Create a fake peer key to receive.
859864 let fake_peer_key = [ 0u8 ; NUM_ELLIGATOR_SWIFT_BYTES ] ;
860865 let handshake = handshake. receive_key ( fake_peer_key) . unwrap ( ) ;
861866
862- // Send version to get to SentVersion state
867+ // Send version to get to SentVersion state.
863868 let mut version_buffer = vec ! [ 0u8 ; 1024 ] ;
864869 let handshake = handshake. send_version ( & mut version_buffer, None ) . unwrap ( ) ;
865870
866- // Test with a buffer that is too long (should fail to find terminator)
871+ // Test with a buffer that is too long (should fail to find terminator).
867872 let test_buffer = vec ! [ 0 ; MAX_NUM_GARBAGE_BYTES + NUM_GARBAGE_TERMINTOR_BYTES ] ;
868873 let result = handshake. split_garbage ( & test_buffer) ;
869874 assert ! ( matches!( result, Err ( Error :: NoGarbageTerminator ) ) ) ;
870875
871- // Test with a buffer that's just short of the required length
876+ // Test with a buffer that's just short of the required length.
872877 let short_buffer = vec ! [ 0 ; MAX_NUM_GARBAGE_BYTES + NUM_GARBAGE_TERMINTOR_BYTES - 1 ] ;
873878 let result = handshake. split_garbage ( & short_buffer) ;
874879 assert ! ( matches!( result, Err ( Error :: CiphertextTooSmall ) ) ) ;
880+
881+ // Even if terminator is present, it's beyond the search limit.
882+ let mut oversized_buffer = vec ! [ 0xEE ; 5000 ] ;
883+ oversized_buffer. extend_from_slice ( & handshake. state . remote_garbage_terminator ) ;
884+ oversized_buffer. extend_from_slice ( & [ 0xFF ; 32 ] ) ;
885+ let result = handshake. split_garbage ( & oversized_buffer) ;
886+ // Should return NoGarbageTerminator because terminator is beyond search limit.
887+ assert ! ( matches!( result, Err ( Error :: NoGarbageTerminator ) ) ) ;
875888 }
876889
877890 // Test that receive_key detects V1 protocol when peer's key starts with network magic.
0 commit comments