[
https://issues.apache.org/jira/browse/SSHD-1197?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Thomas Wolf reassigned SSHD-1197:
---------------------------------
Assignee: Thomas Wolf
> Race condition in KEX
> ---------------------
>
> Key: SSHD-1197
> URL: https://issues.apache.org/jira/browse/SSHD-1197
> Project: MINA SSHD
> Issue Type: Bug
> Affects Versions: 2.7.0
> Reporter: Thomas Wolf
> Assignee: Thomas Wolf
> Priority: Critical
>
> There is a race condition in the KEX implementation. A simple reproducer can
> be obtained by modifying {{SftpTransferTest}} by inserting the following in
> method {{doTestTransferIntegrity()}} just before the main {{try-finally}}:
> {code:java}
> CoreModuleProperties.REKEY_BLOCKS_LIMIT.set(client, Long.valueOf(65536));
> CoreModuleProperties.REKEY_BLOCKS_LIMIT.set(sshd, Long.valueOf(65536));
> try (ClientSession session = createAuthenticatedClientSession();
> ...
> {code}
> This forces rekeying every 512kB; the test roundtrips a 10Mb file twice,
> which gives ample opportunity to run into this race condition. Typically the
> test fails very quickly and hangs.
> The hang is always caused by an async write not being cancelled when the
> session gets disconnected. The session disconnects during KEX because KEX
> state is corrupted because of the race condition.
> Most of the time the race condition causes a signature verification failure
> during KEX, but I also got
> "Disconnecting(ClientSessionImpl[testTransferIntegrity@/127.0.0.1:62186]):
> SSH2_DISCONNECT_KEY_EXCHANGE_FAILED - Unable to negotiate key exchange for
> mac algorithms (server to client) (client: null / server:
> [email protected],[email protected],[email protected],hmac-sha2-256,hmac-sha2-512,hmac-sha1)",
> which is easier to understand than the signature verification failure.
> The precise sequence of events in that case is
> {code:java}
> Server Client
> 1. thread-nio-4 requestNewKeyExchange DONE->INIT
> 2. thread-nio-4 sendKexInit
> 3. main
> requestNewKeyExchange DONE->INIT
> 4. thread-nio-3
> handleKexInit
> 5. thread-nio-3
> doKexNegotiation INIT->RUN
> 6. thread-nio-3
> negotiate -> Exception: client proposal null
> 7. main
> sendKexInit
> 8. thread-nio-2 receive KEX_INIT INIT->RUN
> 9. thread-nio-3
> Exception caught
> 10. thread-nio-3
> Disconnecting
> 11. thread-nio-5 process SSH_MSG_DISCONNECT (KexState RUN)
> {code}
> There is window between steps 3 and 7 in
> {{AbstractSession.requestNewKeyExchange()}} during which the KEX state is
> INIT, but the client proposal isn't initialized yet; it's initialized only
> after {{sendKexInit()}} has been done. However, the client already got the
> server's KEX_INIT message, and in {{doKexNegotiation()}} proceeds as if the
> client proposal was already set up.
> So, theres' two problems here:
> # KEX fails due to a race condition.
> # The client hangs after disconnecting because an async write future is not
> terminated.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]