diff --git a/include/libssh/sftp_priv.h b/include/libssh/sftp_priv.h index 5ee34299..70987b1e 100644 --- a/include/libssh/sftp_priv.h +++ b/include/libssh/sftp_priv.h @@ -52,7 +52,7 @@ int sftp_reply_version(sftp_client_message client_msg); * * @return Length of data decoded. */ -int sftp_decode_channel_data_to_packet(sftp_session sftp, void *data); +int sftp_decode_channel_data_to_packet(sftp_session sftp, void *data, uint32_t len); #ifdef __cplusplus } diff --git a/src/sftp.c b/src/sftp.c index ba19f562..ed353377 100644 --- a/src/sftp.c +++ b/src/sftp.c @@ -360,31 +360,42 @@ void sftp_free(sftp_session sftp) SAFE_FREE(sftp); } -int sftp_decode_channel_data_to_packet(sftp_session sftp, void *data) +/* @internal + * Process the incoming data and copy them from the SSH packet buffer to the + * SFTP packet buffer. + * @returns number of decoded bytes. + */ +int +sftp_decode_channel_data_to_packet(sftp_session sftp, void *data, uint32_t len) { sftp_packet packet = sftp->read_packet; int nread; int payload_len; - int offset; + unsigned int data_offset; int to_read; if (packet->sftp == NULL) { packet->sftp = sftp; } - packet->type = *((uint8_t *)data + sizeof(uint32_t)); - payload_len = PULL_BE_U32(data, 0); - - /* We should check the legality of payload length */ - if (payload_len > MAX_PACKET_LEN || payload_len < 0) { + data_offset = sizeof(uint32_t) + sizeof(uint8_t); + /* not enough bytes to read */ + if (len < data_offset) { + return SSH_ERROR; + } + + payload_len = PULL_BE_U32(data, 0); + packet->type = PULL_BE_U8(data, 4); + + /* We should check the legality of payload length */ + if (payload_len + sizeof(uint32_t) > len || payload_len < 0) { return SSH_ERROR; } - offset = sizeof(int) + sizeof(uint8_t); to_read = payload_len - sizeof(uint8_t); ssh_buffer_add_data(packet->payload, - (void*)((uint8_t *)data + offset), - payload_len - sizeof(uint8_t)); + (void*)((uint8_t *)data + data_offset), + to_read); nread = ssh_buffer_get_len(packet->payload); /* We should check if we copied the whole data */ diff --git a/src/sftpserver.c b/src/sftpserver.c index 0bd85675..8d5ff665 100644 --- a/src/sftpserver.c +++ b/src/sftpserver.c @@ -1702,7 +1702,7 @@ int sftp_channel_default_data_callback(UNUSED_PARAM(ssh_session session), UNUSED_PARAM(ssh_channel channel), void *data, - UNUSED_PARAM(uint32_t len), + uint32_t len, UNUSED_PARAM(int is_stderr), void *userdata) { @@ -1718,7 +1718,7 @@ sftp_channel_default_data_callback(UNUSED_PARAM(ssh_session session), } sftp = *sftpp; - decode_len = sftp_decode_channel_data_to_packet(sftp, data); + decode_len = sftp_decode_channel_data_to_packet(sftp, data, len); if (decode_len == -1) return -1;