sftp: Properly check bounds of incoming packet

Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
This commit is contained in:
Jakub Jelen
2023-03-27 11:33:44 +02:00
parent e5a6dc6757
commit baa18d3712
3 changed files with 24 additions and 13 deletions

View File

@@ -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
}

View File

@@ -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 */

View File

@@ -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;