NTCP2: Fix double-free of buffers after msg3 p2 fails

Fix sending termination after msg3 p2 fails
This commit is contained in:
zzz
2018-07-23 20:50:42 +00:00
parent f554ca3493
commit 18e24edce5
2 changed files with 32 additions and 10 deletions

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */ /** deprecated */
public final static String ID = "Monotone"; public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION; public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 16; public final static long BUILD = 17;
/** for example "-test" */ /** for example "-test" */
public final static String EXTRA = ""; public final static String EXTRA = "";

View File

@ -57,6 +57,8 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
/** how long we expect _sz_aliceIdent_tsA_padding_aliceSig to be when its full */ /** how long we expect _sz_aliceIdent_tsA_padding_aliceSig to be when its full */
private int _sz_aliceIdent_tsA_padding_aliceSigSize; private int _sz_aliceIdent_tsA_padding_aliceSigSize;
private boolean _released;
//// NTCP2 things //// NTCP2 things
private HandshakeState _handshakeState; private HandshakeState _handshakeState;
@ -518,7 +520,10 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
// rather than doing the whole handshake // rather than doing the whole handshake
if(ip != null) if(ip != null)
_context.blocklist().add(ip); _context.blocklist().add(ip);
if (getVersion() < 2)
fail("Peer is banlisted forever: " + aliceHash); fail("Peer is banlisted forever: " + aliceHash);
else if (_log.shouldWarn())
_log.warn("Peer is banlisted forever: " + aliceHash);
_msg3p2FailReason = NTCPConnection.REASON_BANNED; _msg3p2FailReason = NTCPConnection.REASON_BANNED;
return false; return false;
} }
@ -544,7 +549,10 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
aliceHash, aliceHash,
_x("Excessive clock skew: {0}")); _x("Excessive clock skew: {0}"));
_transport.setLastBadSkew(_peerSkew); _transport.setLastBadSkew(_peerSkew);
if (getVersion() < 2)
fail("Clocks too skewed (" + diff + " ms)", null, true); fail("Clocks too skewed (" + diff + " ms)", null, true);
else if (_log.shouldWarn())
_log.warn("Clocks too skewed (" + diff + " ms)");
_msg3p2FailReason = NTCPConnection.REASON_SKEW; _msg3p2FailReason = NTCPConnection.REASON_SKEW;
return false; return false;
} else if (_log.shouldLog(Log.DEBUG)) { } else if (_log.shouldLog(Log.DEBUG)) {
@ -784,13 +792,15 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
// calls callbacks below // calls callbacks below
NTCP2Payload.processPayload(_context, this, payload, 0, _msg3p2len - MAC_SIZE, true); NTCP2Payload.processPayload(_context, this, payload, 0, _msg3p2len - MAC_SIZE, true);
} catch (IOException ioe) { } catch (IOException ioe) {
fail("Bad msg 3 payload", ioe); if (_log.shouldWarn())
_log.warn("Bad msg 3 payload", ioe);
// probably payload frame/block problems // probably payload frame/block problems
// setDataPhase() will send termination // setDataPhase() will send termination
if (_msg3p2FailReason < 0) if (_msg3p2FailReason < 0)
_msg3p2FailReason = NTCPConnection.REASON_FRAMING; _msg3p2FailReason = NTCPConnection.REASON_FRAMING;
} catch (DataFormatException dfe) { } catch (DataFormatException dfe) {
fail("Bad msg 3 payload", dfe); if (_log.shouldWarn())
_log.warn("Bad msg 3 payload", dfe);
// probably RI problems // probably RI problems
// setDataPhase() will send termination // setDataPhase() will send termination
if (_msg3p2FailReason < 0) if (_msg3p2FailReason < 0)
@ -798,7 +808,8 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
_context.statManager().addRateData("ntcp.invalidInboundSignature", 1); _context.statManager().addRateData("ntcp.invalidInboundSignature", 1);
} catch (I2NPMessageException ime) { } catch (I2NPMessageException ime) {
// shouldn't happen, no I2NP msgs in msg3p2 // shouldn't happen, no I2NP msgs in msg3p2
fail("Bad msg 3 payload", ime); if (_log.shouldWarn())
_log.warn("Bad msg 3 payload", ime);
// setDataPhase() will send termination // setDataPhase() will send termination
if (_msg3p2FailReason < 0) if (_msg3p2FailReason < 0)
_msg3p2FailReason = 0; _msg3p2FailReason = 0;
@ -858,11 +869,18 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
} }
/** /**
* KDF for NTCP2 data phase, * KDF for NTCP2 data phase.
* then calls con.finishInboundEstablishment(),
* passing over the final keys and states to the con.
* *
* This changes the state to VERIFIED. * If _msg3p2FailReason is less than zero,
* this calls con.finishInboundEstablishment(),
* passing over the final keys and states to the con,
* and changes the state to VERIFIED.
*
* Otherwise, it calls con.failInboundEstablishment(),
* which will send a termination message,
* and changes the state to CORRUPT.
*
* If you don't call this, call fail().
* *
* @param buf possibly containing "extra" data for data phase * @param buf possibly containing "extra" data for data phase
* @since 0.9.36 * @since 0.9.36
@ -885,6 +903,7 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
if (_log.shouldWarn()) if (_log.shouldWarn())
_log.warn("Failed msg3p2, code " + _msg3p2FailReason + " for " + this); _log.warn("Failed msg3p2, code " + _msg3p2FailReason + " for " + this);
_con.failInboundEstablishment(sender, sip_ba, _msg3p2FailReason); _con.failInboundEstablishment(sender, sip_ba, _msg3p2FailReason);
changeState(State.CORRUPT);
} else { } else {
if (_log.shouldDebug()) { if (_log.shouldDebug()) {
_log.debug("Finished establishment for " + this + _log.debug("Finished establishment for " + this +
@ -1031,6 +1050,9 @@ class InboundEstablishState extends EstablishBase implements NTCP2Payload.Payloa
*/ */
@Override @Override
protected void releaseBufs(boolean isVerified) { protected void releaseBufs(boolean isVerified) {
if (_released)
return;
_released = true;
super.releaseBufs(isVerified); super.releaseBufs(isVerified);
// Do not release _curEncrypted if verified, it is passed to // Do not release _curEncrypted if verified, it is passed to
// NTCPConnection to use as the IV // NTCPConnection to use as the IV