1
0
mirror of https://github.com/libssh2/libssh2.git synced 2025-11-23 01:22:37 +03:00

sftp_symlink: return error if receive buffer too small

and clean up some variable type mismatches

Discussion: http://www.libssh2.org/mail/libssh2-devel-archive-2011-01/0001.shtml
This commit is contained in:
Daniel Stenberg
2011-01-04 14:15:57 +01:00
parent 59207291fc
commit f9b1b95059
2 changed files with 28 additions and 23 deletions

View File

@@ -59,10 +59,13 @@ zero) or negative on failure.
It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While It returns LIBSSH2_ERROR_EAGAIN when it would otherwise block. While
LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se. LIBSSH2_ERROR_EAGAIN is a negative number, it isn't really a failure per se.
From 1.2.8, LIBSSH2_ERROR_BUFFER_TOO_SMALL is returned if the given 'target'
buffer is too small to fit the requested object name.
.SH BUG .SH BUG
Passing in a too small buffer when receiving data only results in libssh2 not Passing in a too small buffer when receiving data only results in libssh2
copying the entire data amount, and it is not possible for the application to 1.2.7 or earlier to not copy the entire data amount, and it is not possible
tell when it happens! for the application to tell when it happens!
.SH ERRORS .SH ERRORS
\fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed. \fILIBSSH2_ERROR_ALLOC\fP - An internal memory allocation call failed.

View File

@@ -2798,7 +2798,7 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
unsigned char *s, *data; unsigned char *s, *data;
static const unsigned char link_responses[2] = static const unsigned char link_responses[2] =
{ SSH_FXP_NAME, SSH_FXP_STATUS }; { SSH_FXP_NAME, SSH_FXP_STATUS };
int rc; int retcode;
if ((sftp->version < 3) && (link_type != LIBSSH2_SFTP_REALPATH)) { if ((sftp->version < 3) && (link_type != LIBSSH2_SFTP_REALPATH)) {
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
@@ -2845,11 +2845,11 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
} }
if (sftp->symlink_state == libssh2_NB_state_created) { if (sftp->symlink_state == libssh2_NB_state_created) {
rc = _libssh2_channel_write(channel, 0, sftp->symlink_packet, ssize_t rc = _libssh2_channel_write(channel, 0, sftp->symlink_packet,
packet_len); packet_len);
if (rc == LIBSSH2_ERROR_EAGAIN) { if (rc == LIBSSH2_ERROR_EAGAIN)
return rc; return rc;
} else if (packet_len != rc) { else if (packet_len != rc) {
LIBSSH2_FREE(session, sftp->symlink_packet); LIBSSH2_FREE(session, sftp->symlink_packet);
sftp->symlink_packet = NULL; sftp->symlink_packet = NULL;
sftp->symlink_state = libssh2_NB_state_idle; sftp->symlink_state = libssh2_NB_state_idle;
@@ -2862,13 +2862,12 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
sftp->symlink_state = libssh2_NB_state_sent; sftp->symlink_state = libssh2_NB_state_sent;
} }
rc = sftp_packet_requirev(sftp, 2, link_responses, retcode = sftp_packet_requirev(sftp, 2, link_responses,
sftp->symlink_request_id, &data, sftp->symlink_request_id, &data,
&data_len); &data_len);
if (rc == LIBSSH2_ERROR_EAGAIN) { if (retcode == LIBSSH2_ERROR_EAGAIN)
return rc; return retcode;
} else if (retcode) {
else if (rc) {
sftp->symlink_state = libssh2_NB_state_idle; sftp->symlink_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT, return _libssh2_error(session, LIBSSH2_ERROR_SOCKET_TIMEOUT,
"Timeout waiting for status message"); "Timeout waiting for status message");
@@ -2881,9 +2880,9 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
retcode = _libssh2_ntohu32(data + 5); retcode = _libssh2_ntohu32(data + 5);
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
if (retcode == LIBSSH2_FX_OK) { if (retcode == LIBSSH2_FX_OK)
return 0; return LIBSSH2_ERROR_NONE;
} else { else {
sftp->last_errno = retcode; sftp->last_errno = retcode;
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL, return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error"); "SFTP Protocol Error");
@@ -2897,15 +2896,18 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
"no name entries"); "no name entries");
} }
/* this reads a u32 and stores it into a signed 32bit value */
link_len = _libssh2_ntohu32(data + 9); link_len = _libssh2_ntohu32(data + 9);
if (link_len >= target_len) { if (link_len < target_len) {
link_len = target_len - 1; memcpy(target, data + 13, link_len);
target[link_len] = 0;
retcode = (int)link_len;
} }
memcpy(target, data + 13, link_len); else
target[link_len] = 0; retcode = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
LIBSSH2_FREE(session, data); LIBSSH2_FREE(session, data);
return link_len; return retcode;
} }
/* libssh2_sftp_symlink_ex /* libssh2_sftp_symlink_ex