summaryrefslogtreecommitdiff
path: root/libs/libssh2/src/sftp.c
diff options
context:
space:
mode:
authorGeorge Hazan <ghazan@miranda.im>2019-03-15 16:04:01 +0300
committerGeorge Hazan <ghazan@miranda.im>2019-03-15 16:04:01 +0300
commit7b425e06f940fbc0a1d962bee7695530fcc70ceb (patch)
treefb232f9f2066ccf19ce46ec8d92fdc2534f4c938 /libs/libssh2/src/sftp.c
parent2084ac854656d90a030de560d69d6c5080f9bb00 (diff)
libssh updated to 1.8.1
Diffstat (limited to 'libs/libssh2/src/sftp.c')
-rw-r--r--libs/libssh2/src/sftp.c317
1 files changed, 260 insertions, 57 deletions
diff --git a/libs/libssh2/src/sftp.c b/libs/libssh2/src/sftp.c
index 7c44116401..fd94d39029 100644
--- a/libs/libssh2/src/sftp.c
+++ b/libs/libssh2/src/sftp.c
@@ -204,6 +204,10 @@ sftp_packet_add(LIBSSH2_SFTP *sftp, unsigned char *data,
LIBSSH2_SFTP_PACKET *packet;
uint32_t request_id;
+ if (data_len < 5) {
+ return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+ }
+
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Received packet type %d (len %d)",
(int) data[0], data_len);
@@ -345,6 +349,10 @@ sftp_packet_read(LIBSSH2_SFTP *sftp)
return _libssh2_error(session,
LIBSSH2_ERROR_CHANNEL_PACKET_EXCEEDED,
"SFTP packet too large");
+ if (sftp->partial_len == 0)
+ return _libssh2_error(session,
+ LIBSSH2_ERROR_ALLOC,
+ "Unable to allocate empty SFTP packet");
_libssh2_debug(session, LIBSSH2_TRACE_SFTP,
"Data begin - Packet Length: %lu",
@@ -504,11 +512,15 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsigned char packet_type,
static int
sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
uint32_t request_id, unsigned char **data,
- size_t *data_len)
+ size_t *data_len, size_t required_size)
{
LIBSSH2_SESSION *session = sftp->channel->session;
int rc;
+ if (data == NULL || data_len == NULL || required_size == 0) {
+ return LIBSSH2_ERROR_BAD_USE;
+ }
+
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Requiring packet %d id %ld",
(int) packet_type, request_id);
@@ -516,6 +528,11 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
/* The right packet was available in the packet brigade */
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d",
(int) packet_type);
+
+ if (*data_len < required_size) {
+ return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+ }
+
return LIBSSH2_ERROR_NONE;
}
@@ -529,6 +546,11 @@ sftp_packet_require(LIBSSH2_SFTP *sftp, unsigned char packet_type,
/* The right packet was available in the packet brigade */
_libssh2_debug(session, LIBSSH2_TRACE_SFTP, "Got %d",
(int) packet_type);
+
+ if (*data_len < required_size) {
+ return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+ }
+
return LIBSSH2_ERROR_NONE;
}
}
@@ -544,11 +566,15 @@ static int
sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
const unsigned char *valid_responses,
uint32_t request_id, unsigned char **data,
- size_t *data_len)
+ size_t *data_len, size_t required_size)
{
int i;
int rc;
+ if (data == NULL || data_len == NULL || required_size == 0) {
+ return LIBSSH2_ERROR_BAD_USE;
+ }
+
/* If no timeout is active, start a new one */
if (sftp->requirev_start == 0)
sftp->requirev_start = time(NULL);
@@ -562,6 +588,11 @@ sftp_packet_requirev(LIBSSH2_SFTP *sftp, int num_valid_responses,
* the timeout is not active
*/
sftp->requirev_start = 0;
+
+ if (*data_len < required_size) {
+ return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+ }
+
return LIBSSH2_ERROR_NONE;
}
}
@@ -636,36 +667,65 @@ sftp_attr2bin(unsigned char *p, const LIBSSH2_SFTP_ATTRIBUTES * attrs)
/* sftp_bin2attr
*/
static int
-sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES * attrs, const unsigned char *p)
+sftp_bin2attr(LIBSSH2_SFTP_ATTRIBUTES * attrs, const unsigned char *p, size_t data_len)
{
const unsigned char *s = p;
- memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
- attrs->flags = _libssh2_ntohu32(s);
- s += 4;
+ if (data_len >= 4) {
+ memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
+ attrs->flags = _libssh2_ntohu32(s);
+ s += 4;
+ data_len -= 4;
+ }
+ else {
+ return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+ }
if (attrs->flags & LIBSSH2_SFTP_ATTR_SIZE) {
- attrs->filesize = _libssh2_ntohu64(s);
- s += 8;
+ if (data_len >= 8) {
+ attrs->filesize = _libssh2_ntohu64(s);
+ s += 8;
+ data_len -= 8;
+ }
+ else {
+ return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+ }
}
if (attrs->flags & LIBSSH2_SFTP_ATTR_UIDGID) {
- attrs->uid = _libssh2_ntohu32(s);
- s += 4;
- attrs->gid = _libssh2_ntohu32(s);
- s += 4;
+ if (data_len >= 8) {
+ attrs->uid = _libssh2_ntohu32(s);
+ s += 4;
+ attrs->gid = _libssh2_ntohu32(s);
+ s += 4;
+ data_len -= 8;
+ }
+ else {
+ return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+ }
}
if (attrs->flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) {
- attrs->permissions = _libssh2_ntohu32(s);
- s += 4;
+ if (data_len >= 4) {
+ attrs->permissions = _libssh2_ntohu32(s);
+ s += 4;
+ data_len -= 4;
+ }
+ else {
+ return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+ }
}
if (attrs->flags & LIBSSH2_SFTP_ATTR_ACMODTIME) {
- attrs->atime = _libssh2_ntohu32(s);
- s += 4;
- attrs->mtime = _libssh2_ntohu32(s);
- s += 4;
+ if (data_len >= 8) {
+ attrs->atime = _libssh2_ntohu32(s);
+ s += 4;
+ attrs->mtime = _libssh2_ntohu32(s);
+ s += 4;
+ }
+ else {
+ return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
+ }
}
return (s - p);
@@ -835,18 +895,23 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_SESSION *session)
}
rc = sftp_packet_require(sftp_handle, SSH_FXP_VERSION,
- 0, &data, &data_len);
- if (rc == LIBSSH2_ERROR_EAGAIN)
+ 0, &data, &data_len, 5);
+ if (rc == LIBSSH2_ERROR_EAGAIN) {
+ _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
+ "Would block receiving SSH_FXP_VERSION");
return NULL;
- else if (rc) {
- _libssh2_error(session, rc,
- "Timeout waiting for response from SFTP subsystem");
- goto sftp_init_error;
}
- if (data_len < 5) {
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
_libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"Invalid SSH_FXP_VERSION response");
- LIBSSH2_FREE(session, data);
+ goto sftp_init_error;
+ }
+ else if (rc) {
+ _libssh2_error(session, rc,
+ "Timeout waiting for response from SFTP subsystem");
goto sftp_init_error;
}
@@ -1112,12 +1177,20 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
{ SSH_FXP_HANDLE, SSH_FXP_STATUS };
rc = sftp_packet_requirev(sftp, 2, fopen_responses,
sftp->open_request_id, &data,
- &data_len);
+ &data_len, 1);
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block waiting for status message");
return NULL;
}
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "Response too small");
+ return NULL;
+ }
sftp->open_state = libssh2_NB_state_idle;
if (rc) {
_libssh2_error(session, rc, "Timeout waiting for status message");
@@ -1148,12 +1221,20 @@ sftp_open(LIBSSH2_SFTP *sftp, const char *filename,
/* silly situation, but check for a HANDLE */
rc = sftp_packet_require(sftp, SSH_FXP_HANDLE,
sftp->open_request_id, &data,
- &data_len);
+ &data_len, 10);
if(rc == LIBSSH2_ERROR_EAGAIN) {
/* go back to sent state and wait for something else */
sftp->open_state = libssh2_NB_state_sent;
return NULL;
}
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "Too small FXP_HANDLE");
+ return NULL;
+ }
else if(!rc)
/* we got the handle so this is not a bad situation */
badness = 0;
@@ -1480,15 +1561,21 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HANDLE * handle, char *buffer,
}
rc = sftp_packet_requirev(sftp, 2, read_responses,
- chunk->request_id, &data, &data_len);
-
- if (rc==LIBSSH2_ERROR_EAGAIN && bytes_in_buffer != 0) {
+ chunk->request_id, &data, &data_len, 9);
+ if (rc == LIBSSH2_ERROR_EAGAIN && bytes_in_buffer != 0) {
/* do not return EAGAIN if we have already
* written data into the buffer */
return bytes_in_buffer;
}
- if (rc < 0) {
+ if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "Response too small");
+ }
+ else if(rc < 0) {
sftp->read_state = libssh2_NB_state_sent2;
return rc;
}
@@ -1698,7 +1785,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
if (attrs)
memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
- s += sftp_bin2attr(attrs ? attrs : &attrs_dummy, s);
+ s += sftp_bin2attr(attrs ? attrs : &attrs_dummy, s, 32);
handle->u.dir.next_name = (char *) s;
end:
@@ -1753,9 +1840,16 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP_HANDLE *handle, char *buffer,
retcode = sftp_packet_requirev(sftp, 2, read_responses,
sftp->readdir_request_id, &data,
- &data_len);
+ &data_len, 9);
if (retcode == LIBSSH2_ERROR_EAGAIN)
return retcode;
+ else if (retcode == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "Status message too short");
+ }
else if (retcode) {
sftp->readdir_state = libssh2_NB_state_idle;
return _libssh2_error(session, retcode,
@@ -1981,8 +2075,15 @@ static ssize_t sftp_write(LIBSSH2_SFTP_HANDLE *handle, const char *buffer,
/* we check the packets in order */
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
- chunk->request_id, &data, &data_len);
- if (rc < 0) {
+ chunk->request_id, &data, &data_len, 9);
+ if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "FXP write packet too short");
+ }
+ else if (rc < 0) {
if (rc == LIBSSH2_ERROR_EAGAIN)
sftp->write_state = libssh2_NB_state_sent;
return rc;
@@ -2124,10 +2225,18 @@ static int sftp_fsync(LIBSSH2_SFTP_HANDLE *handle)
}
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
- sftp->fsync_request_id, &data, &data_len);
+ sftp->fsync_request_id, &data, &data_len, 9);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc) {
+ }
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "SFTP fsync packet too short");
+ }
+ else if (rc) {
sftp->fsync_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Error waiting for FXP EXTENDED REPLY");
@@ -2227,9 +2336,16 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
rc = sftp_packet_requirev(sftp, 2, fstat_responses,
sftp->fstat_request_id, &data,
- &data_len);
+ &data_len, 9);
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "SFTP fstat packet too short");
+ }
else if (rc) {
sftp->fstat_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
@@ -2252,7 +2368,12 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDLE *handle,
}
}
- sftp_bin2attr(attrs, data + 5);
+ if (sftp_bin2attr(attrs, data + 5, data_len - 5) < 0) {
+ LIBSSH2_FREE(session, data);
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "Attributes too short in SFTP fstat");
+ }
+
LIBSSH2_FREE(session, data);
return 0;
@@ -2429,11 +2550,19 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle)
if (handle->close_state == libssh2_NB_state_sent) {
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
handle->close_request_id, &data,
- &data_len);
+ &data_len, 9);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
-
- } else if (rc) {
+ }
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ data = NULL;
+ _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "Packet too short in FXP_CLOSE command");
+ }
+ else if (rc) {
_libssh2_error(session, rc,
"Error waiting for status message");
}
@@ -2547,10 +2676,17 @@ static int sftp_unlink(LIBSSH2_SFTP *sftp, const char *filename,
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
sftp->unlink_request_id, &data,
- &data_len);
+ &data_len, 9);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
}
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "SFTP unlink packet too short");
+ }
else if (rc) {
sftp->unlink_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
@@ -2658,10 +2794,18 @@ static int sftp_rename(LIBSSH2_SFTP *sftp, const char *source_filename,
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
sftp->rename_request_id, &data,
- &data_len);
+ &data_len, 9);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc) {
+ }
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "SFTP rename packet too short");
+ }
+ else if (rc) {
sftp->rename_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Error waiting for FXP STATUS");
@@ -2783,11 +2927,19 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle, LIBSSH2_SFTP_STATVFS *st)
}
rc = sftp_packet_requirev(sftp, 2, responses, sftp->fstatvfs_request_id,
- &data, &data_len);
+ &data, &data_len, 9);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc) {
+ }
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "SFTP rename packet too short");
+ }
+ else if (rc) {
sftp->fstatvfs_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Error waiting for FXP EXTENDED REPLY");
@@ -2910,10 +3062,18 @@ static int sftp_statvfs(LIBSSH2_SFTP *sftp, const char *path,
}
rc = sftp_packet_requirev(sftp, 2, responses, sftp->statvfs_request_id,
- &data, &data_len);
+ &data, &data_len, 9);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc) {
+ }
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "SFTP fstat packet too short");
+ }
+ else if (rc) {
sftp->statvfs_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Error waiting for FXP EXTENDED REPLY");
@@ -3040,10 +3200,18 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp, const char *path,
}
rc = sftp_packet_require(sftp, SSH_FXP_STATUS, sftp->mkdir_request_id,
- &data, &data_len);
+ &data, &data_len, 9);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc) {
+ }
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "SFTP mkdir packet too short");
+ }
+ else if (rc) {
sftp->mkdir_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Error waiting for FXP STATUS");
@@ -3134,10 +3302,18 @@ static int sftp_rmdir(LIBSSH2_SFTP *sftp, const char *path,
}
rc = sftp_packet_require(sftp, SSH_FXP_STATUS,
- sftp->rmdir_request_id, &data, &data_len);
+ sftp->rmdir_request_id, &data, &data_len, 9);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc) {
+ }
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "SFTP rmdir packet too short");
+ }
+ else if (rc) {
sftp->rmdir_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"Error waiting for FXP STATUS");
@@ -3247,9 +3423,16 @@ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path,
}
rc = sftp_packet_requirev(sftp, 2, stat_responses,
- sftp->stat_request_id, &data, &data_len);
+ sftp->stat_request_id, &data, &data_len, 9);
if (rc == LIBSSH2_ERROR_EAGAIN)
return rc;
+ else if (rc == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "SFTP stat packet too short");
+ }
else if (rc) {
sftp->stat_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
@@ -3273,7 +3456,12 @@ static int sftp_stat(LIBSSH2_SFTP *sftp, const char *path,
}
memset(attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
- sftp_bin2attr(attrs, data + 5);
+ if (sftp_bin2attr(attrs, data + 5, data_len - 5) < 0) {
+ LIBSSH2_FREE(session, data);
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "Attributes too short in SFTP fstat");
+ }
+
LIBSSH2_FREE(session, data);
return 0;
@@ -3378,9 +3566,16 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
retcode = sftp_packet_requirev(sftp, 2, link_responses,
sftp->symlink_request_id, &data,
- &data_len);
+ &data_len, 9);
if (retcode == LIBSSH2_ERROR_EAGAIN)
return retcode;
+ else if (retcode == LIBSSH2_ERROR_OUT_OF_BOUNDARY) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "SFTP symlink packet too short");
+ }
else if (retcode) {
sftp->symlink_state = libssh2_NB_state_idle;
return _libssh2_error(session, retcode,
@@ -3410,6 +3605,14 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
"no name entries");
}
+ if (data_len < 13) {
+ if (data_len > 0) {
+ LIBSSH2_FREE(session, data);
+ }
+ return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
+ "SFTP stat packet too short");
+ }
+
/* this reads a u32 and stores it into a signed 32bit value */
link_len = _libssh2_ntohu32(data + 9);
if (link_len < target_len) {