mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-11 10:40:27 +09:00
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:
@@ -52,7 +52,7 @@ int sftp_reply_version(sftp_client_message client_msg);
|
|||||||
*
|
*
|
||||||
* @return Length of data decoded.
|
* @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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/sftp.c
31
src/sftp.c
@@ -360,31 +360,42 @@ void sftp_free(sftp_session sftp)
|
|||||||
SAFE_FREE(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;
|
sftp_packet packet = sftp->read_packet;
|
||||||
int nread;
|
int nread;
|
||||||
int payload_len;
|
int payload_len;
|
||||||
int offset;
|
unsigned int data_offset;
|
||||||
int to_read;
|
int to_read;
|
||||||
|
|
||||||
if (packet->sftp == NULL) {
|
if (packet->sftp == NULL) {
|
||||||
packet->sftp = sftp;
|
packet->sftp = sftp;
|
||||||
}
|
}
|
||||||
|
|
||||||
packet->type = *((uint8_t *)data + sizeof(uint32_t));
|
data_offset = sizeof(uint32_t) + sizeof(uint8_t);
|
||||||
payload_len = PULL_BE_U32(data, 0);
|
/* not enough bytes to read */
|
||||||
|
if (len < data_offset) {
|
||||||
/* We should check the legality of payload length */
|
return SSH_ERROR;
|
||||||
if (payload_len > MAX_PACKET_LEN || payload_len < 0) {
|
}
|
||||||
|
|
||||||
|
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;
|
return SSH_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = sizeof(int) + sizeof(uint8_t);
|
|
||||||
to_read = payload_len - sizeof(uint8_t);
|
to_read = payload_len - sizeof(uint8_t);
|
||||||
ssh_buffer_add_data(packet->payload,
|
ssh_buffer_add_data(packet->payload,
|
||||||
(void*)((uint8_t *)data + offset),
|
(void*)((uint8_t *)data + data_offset),
|
||||||
payload_len - sizeof(uint8_t));
|
to_read);
|
||||||
nread = ssh_buffer_get_len(packet->payload);
|
nread = ssh_buffer_get_len(packet->payload);
|
||||||
|
|
||||||
/* We should check if we copied the whole data */
|
/* We should check if we copied the whole data */
|
||||||
|
|||||||
@@ -1702,7 +1702,7 @@ int
|
|||||||
sftp_channel_default_data_callback(UNUSED_PARAM(ssh_session session),
|
sftp_channel_default_data_callback(UNUSED_PARAM(ssh_session session),
|
||||||
UNUSED_PARAM(ssh_channel channel),
|
UNUSED_PARAM(ssh_channel channel),
|
||||||
void *data,
|
void *data,
|
||||||
UNUSED_PARAM(uint32_t len),
|
uint32_t len,
|
||||||
UNUSED_PARAM(int is_stderr),
|
UNUSED_PARAM(int is_stderr),
|
||||||
void *userdata)
|
void *userdata)
|
||||||
{
|
{
|
||||||
@@ -1718,7 +1718,7 @@ sftp_channel_default_data_callback(UNUSED_PARAM(ssh_session session),
|
|||||||
}
|
}
|
||||||
sftp = *sftpp;
|
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)
|
if (decode_len == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user