Subject: | Race condition in KEXINIT |
During the KEXINIT process, if the server's initial Key Exchange
negotiation packet is received before the Net::SSH::Perl client sends
the TCP ACK packet for the Protocol Version Exchange, the negotiation
packet is ignored and the connection process hangs. For example, a
"good" connection looks something like this:
CLIENT --> SERVER --- SYN
CLIENT <-- SERVER --- SYN ACK
CLIENT --> SERVER --- ACK
CLIENT <-- SERVER --- Server Protocol Version Packet
CLIENT --> SERVER --- ACK
CLIENT <-- SERVER --- KEXINIT proposal from server
CLIENT --> SERVER --- ACK
CLIENT --> SERVER --- Client Protocol Version Packet
CLIENT <-- SERVER --- ACK
CLIENT --> SERVER --- KEXINIT proposal from client (and sometimes DH
Exchange Init)
CLIENT <-- SERVER --- ACK
(DH negotiation proceeds, etc.)
Here's an example of a sequence that will create a hang:
CLIENT --> SERVER --- SYN
CLIENT <-- SERVER --- SYN ACK
CLIENT --> SERVER --- ACK
CLIENT <-- SERVER --- Server Protocol Version Packet
CLIENT <-- SERVER --- KEXINIT proposal from server
CLIENT --> SERVER --- ACK
CLIENT --> SERVER --- ACK
CLIENT --> SERVER --- Client Protocol Version Packet
CLIENT <-- SERVER --- ACK
CLIENT --> SERVER --- KEXINIT proposal from client
CLIENT <-- SERVER --- ACK
(process hangs waiting for the Server's KEXINIT proposal)
The specific system I'm running is Perl 5.8.8 for
x86_64-linux-gnu-thread-multi running on Ubuntu 8.04 LTS (kernel
2.6.24-26-server) on VMWare ESXi 4. The virtualization may be what's
slowing down the script enough so that the race condition occurs; I
would imagine that in other circumstances it'd be pretty hard to trigger
this bug.