1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-08-08 19:02:06 +03:00

packet: Do not decrypt zero length rest of buffer

If we receive a packet of length exactly blocksize, then
packet_decrypt gets called on a buffer of size 0.  The check at the
beginning of packet_decrypt indicates that the function should be
called on buffers of at least one blocksize, though the check allows
through zero length.  As is packet_decrypt can return -1 when len is 0
because malloc can return NULL in this case: according to the ISO C
standard, malloc is free to return NULL or a pointer that can be freed
when size == 0, and uclibc by default will return NULL here (in
"non-glibc-compatible" mode).  The net result is that when using
uclibc connections with libssh can anomalously fail.

Alternatively, packet_decrypt (and probably packet_encrypt for
consistency) could be made to always succeed on len == 0 without
depending on the behavior of malloc.

Thanks to Josh Berlin for bringing conneciton failures with uclibc to
my attention.

Signed-off-by: Alan Dunn <amdunn@gmail.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Alan Dunn
2014-02-06 08:12:46 -06:00
committed by Andreas Schneider
parent 4ea4e12df2
commit e7f831f0a3
2 changed files with 25 additions and 13 deletions

View File

@@ -152,7 +152,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
const uint8_t *packet;
int to_be_read;
int rc;
uint32_t len, compsize, payloadsize;
uint32_t len, compsize, payloadsize, buffer_len;
uint8_t padding;
size_t processed = 0; /* number of byte processed from the callback */
@@ -251,12 +251,17 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
* Decrypt the rest of the packet (blocksize bytes already
* have been decrypted)
*/
rc = packet_decrypt(session,
((uint8_t*)buffer_get_rest(session->in_buffer) + blocksize),
buffer_get_rest_len(session->in_buffer) - blocksize);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL, "Decrypt error");
goto error;
/* The following check avoids decrypting zero bytes */
buffer_len = buffer_get_rest_len(session->in_buffer);
if (buffer_len != blocksize) {
rc = packet_decrypt(session,
((uint8_t*)buffer_get_rest(session->in_buffer) + blocksize),
buffer_len - blocksize);
if (rc < 0) {
ssh_set_error(session, SSH_FATAL, "Decrypt error");
goto error;
}
}
/* copy the last part from the incoming buffer */