diff --git a/include/libssh2.h b/include/libssh2.h index 6efc8799..154b0370 100644 --- a/include/libssh2.h +++ b/include/libssh2.h @@ -117,10 +117,13 @@ #define LIBSSH2_SOCKET_POLL_MAXLOOPS 120 /* Maximum size to allow a payload to compress to, plays it safe by falling short of spec limits */ -#define LIBSSH2_PACKET_MAXCOMP 32000 +#define LIBSSH2_PACKET_MAXCOMP 32000 /* Maximum size to allow a payload to deccompress to, plays it safe by allowing more than spec requires */ -#define LIBSSH2_PACKET_MAXDECOMP 40000 +#define LIBSSH2_PACKET_MAXDECOMP 40000 + +/* Maximum size for an inbound compressed payload, plays it safe by overshooting spec limits */ +#define LIBSSH2_PACKET_MAXPAYLOAD 40000 /* Malloc callbacks */ #define LIBSSH2_ALLOC_FUNC(name) void *name(size_t count, void **abstract) diff --git a/src/packet.c b/src/packet.c index 7db5ada5..13e00548 100644 --- a/src/packet.c +++ b/src/packet.c @@ -364,6 +364,16 @@ int libssh2_packet_read(LIBSSH2_SESSION *session, int should_block) memcpy(tmp, block, 5); /* Use this for MAC later */ payload_len = packet_len - 1; /* padding_len(1) */ + /* Sanity Check */ + if ((payload_len > LIBSSH2_PACKET_MAXPAYLOAD) || + ((packet_len + 4) % blocksize)) { + /* If something goes horribly wrong during the decryption phase, just bailout and die gracefully */ + LIBSSH2_FREE(session, block); + session->socket_state = LIBSSH2_SOCKET_DISCONNECTED; + libssh2_error(session, LIBSSH2_ERROR_PROTO, "Fatal protocol error, invalid payload size", 0); + return -1; + } + s = payload = LIBSSH2_ALLOC(session, payload_len); memcpy(s, block + 5, blocksize - 5); s += blocksize - 5;