atl-dyon opened a new issue, #927:
URL: https://github.com/apache/mina-sshd/issues/927

   ### Version
   
   2.14.0
   
   ### Bug description
   
   SSHD 2.14.0 and later can run kex.init on the thread that writes data, while 
an I/O thread handles the next key exchange packet. The I/O thread then uses a 
key exchange that is not ready. The session fails with "ECDH not initialised" 
or a NullPointerException. The client sees "early EOF"
   
   We first observed this in sshd 2.16.0 in Bitbucket DC 10.2.
   
   ## Reproducer
   `RekeyRace.java` is attached. It uses the public API only.
   
   ```
   mvn -q compile exec:java -Dexec.args="65536 33554432 20 8 0 0"
   mvn -q compile exec:java -Dexec.args="65536 33554432 20 8 0 0" 
-Dsshd.version=2.13.2
   ```
   
   - 2.16.0: failed in 5 of 5 runs.
   - 2.13.2: passed 4 of 4 runs.
   
   The server writes from its own thread, and both sides use the same re-key 
limit.
   
   I also ran `git clone` against a server on 2.16.0 with OpenSSH 10.3 as the 
client. With a 64K re-key limit on both sides, all rounds failed. 
   
   ## Cause
   I think this comes from 9e4e040e, "Clean-up: timeout-free KEX". It replaced 
`initFuture.await()` with `initFuture.addListener()` in `doKexNegotiation`. The 
listener can run `performKexNegotiation`, and so `kex.init`, on the thread that 
completes the future. That can be the thread that writes channel data. An I/O 
thread can reach `kex.next` while this runs.
   
   I tried a subclass of `ServerSessionImpl` that waits on `kexState` before 
`handleKexMessage`. This allowed me to pass testing and not observe the bug. 
   
   Note that the `ReKeyRace.java` is AI generated but accurately showcases the 
issue. 
   
   
[RekeyRace.java](https://github.com/user-attachments/files/33366384/RekeyRace.java)
   
   
   
   ### Actual behavior
   
   An `nio2` thread throws from `AbstractSession.handleKexMessage`:
   
   ```
   java.lang.NullPointerException: Cannot invoke "KeyExchange.next(int, 
Buffer)" because "this.kex" is null
   java.lang.IllegalStateException: ECDH not initialised.
   java.lang.IllegalStateException: Not initialized
   ```
   
   ```
   at org.apache.sshd.server.kex.DHGServer.next(DHGServer.java:109)
   at 
org.apache.sshd.common.session.helpers.AbstractSession.handleKexMessage(AbstractSession.java:771)
   at 
org.apache.sshd.common.session.helpers.AbstractSession.messageReceived(AbstractSession.java:515)
   at 
org.apache.sshd.common.io.nio2.Nio2Session.handleReadCycleCompletion(Nio2Session.java:409)
   ```
   
   ### Expected behavior
   
   Rekey should occur without error, and the session transfer continues to 
completion. 
   
   ### Relevant log output
   
   ```Shell
   
   ```
   
   ### Other information
   
   _No response_


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to