Backport patches for libssh2 CVEs. Bump version string.

This commit is contained in:
dmiller 2026-07-27 15:55:34 +00:00
parent e2265fe97c
commit 693a2606b6
6 changed files with 78 additions and 25 deletions

View file

@ -48,7 +48,7 @@
to make the BANNER define (used by src/session.c) be a valid SSH
banner. Release versions have no appended strings and may of course not
have dashes either. */
#define LIBSSH2_VERSION "1.11.1"
#define LIBSSH2_VERSION "1.11.1_NMAP1"
/* The numeric version number is also available "in parts" by using these
defines: */
@ -82,7 +82,7 @@
*
* "Mon Feb 12 11:35:33 UTC 2007"
*/
#define LIBSSH2_TIMESTAMP "Wed Oct 16 08:03:21 UTC 2024"
#define LIBSSH2_TIMESTAMP "Wed Jul 27 15:27:00 UTC 2026"
#ifndef RC_INVOKED

View file

@ -117,6 +117,14 @@
#define UINT32_MAX 0xffffffffU
#endif
#ifdef _WIN64
#define LIBSSH2_UNCONST(p) ((void *)(libssh2_uint64_t)(const void *)(p))
#elif defined(_MSC_VER)
#define LIBSSH2_UNCONST(p) ((void *)(unsigned int)(const void *)(p))
#else
#define LIBSSH2_UNCONST(p) ((void *)(uintptr_t)(const void *)(p))
#endif
#if (defined(__GNUC__) || defined(__clang__)) && \
defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \
!defined(LIBSSH2_NO_FMT_CHECKS)

View file

@ -868,8 +868,10 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
nr_extensions -= 1;
_libssh2_get_string(&buf, &name, &name_len);
_libssh2_get_string(&buf, &value, &value_len);
if(_libssh2_get_string(&buf, &name, &name_len))
break;
if(_libssh2_get_string(&buf, &value, &value_len))
break;
if(name && value) {
_libssh2_debug((session,

View file

@ -3795,15 +3795,19 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
{
LIBSSH2_CHANNEL *channel = sftp->channel;
LIBSSH2_SESSION *session = channel->session;
size_t data_len = 0, link_len;
size_t data_len = 0, lk_len;
/* 13 = packet_len(4) + packet_type(1) + request_id(4) + path_len(4) */
ssize_t packet_len =
path_len + 13 +
((link_type == LIBSSH2_SFTP_SYMLINK) ? (4 + target_len) : 0);
unsigned char *s, *data = NULL;
struct string_buf buf;
static const unsigned char link_responses[2] =
{ SSH_FXP_NAME, SSH_FXP_STATUS };
int retcode;
unsigned char packet_type;
uint32_t tmp_u32;
unsigned char *lk_target;
if(sftp->symlink_state == libssh2_NB_state_idle) {
sftp->last_errno = LIBSSH2_FX_OK;
@ -3891,8 +3895,25 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
sftp->symlink_state = libssh2_NB_state_idle;
if(data[0] == SSH_FXP_STATUS) {
retcode = _libssh2_ntohu32(data + 5);
buf.data = (unsigned char *)LIBSSH2_UNCONST(data);
buf.dataptr = buf.data;
buf.len = data_len;
if(_libssh2_get_byte(&buf, &packet_type)) {
LIBSSH2_FREE(session, data);
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error (type)");
}
if(packet_type == SSH_FXP_STATUS) {
if(_libssh2_get_u32(&buf, &tmp_u32)) {
LIBSSH2_FREE(session, data);
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error (code)");
}
retcode = (int)tmp_u32;
LIBSSH2_FREE(session, data);
if(retcode == LIBSSH2_FX_OK)
return LIBSSH2_ERROR_NONE;
@ -3903,30 +3924,37 @@ static int sftp_symlink(LIBSSH2_SFTP *sftp, const char *path,
}
}
if(_libssh2_ntohu32(data + 5) < 1) {
/* advance past id */
if(_libssh2_get_u32(&buf, &tmp_u32)) {
LIBSSH2_FREE(session, data);
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"Invalid READLINK/REALPATH response, "
"no name entries");
"SFTP Protocol Error (id)");
}
if(data_len < 13) {
if(data_len > 0) {
LIBSSH2_FREE(session, data);
}
/* look for at least one link */
if(_libssh2_get_u32(&buf, &tmp_u32) || tmp_u32 < 1) {
LIBSSH2_FREE(session, data);
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP stat packet too short");
"Invalid READLINK/REALPATH response, "
"no name entries");
}
/* this reads a u32 and stores it into a signed 32bit value */
link_len = _libssh2_ntohu32(data + 9);
if(link_len < target_len) {
memcpy(target, data + 13, link_len);
target[link_len] = 0;
retcode = (int)link_len;
if(_libssh2_get_string(&buf, &lk_target, &lk_len) == LIBSSH2_ERROR_NONE) {
if(lk_len < target_len) {
memcpy(target, lk_target, lk_len);
target[lk_len] = '\0';
retcode = (int)lk_len;
}
else {
retcode = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
}
}
else
retcode = LIBSSH2_ERROR_BUFFER_TOO_SMALL;
else {
LIBSSH2_FREE(session, data);
return _libssh2_error(session, LIBSSH2_ERROR_SFTP_PROTOCOL,
"SFTP Protocol Error (filename)");
}
LIBSSH2_FREE(session, data);
return retcode;

View file

@ -639,8 +639,12 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
total_num = 4;
p->packet_length = _libssh2_ntohu32(block);
if(p->packet_length < 1)
if(p->packet_length < 1) {
return LIBSSH2_ERROR_DECRYPT;
}
else if(p->packet_length > LIBSSH2_PACKET_MAXPAYLOAD) {
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
}
/* total_num may include size field, however due to existing
* logic it needs to be removed after the entire packet is read

View file

@ -80,6 +80,12 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
memset(&session->userauth_list_packet_requirev_state, 0,
sizeof(session->userauth_list_packet_requirev_state));
if(username_len > UINT32_MAX - 27) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
"username_len out of bounds");
return NULL;
}
session->userauth_list_data_len = username_len + 27;
s = session->userauth_list_data =
@ -307,6 +313,11 @@ userauth_password(LIBSSH2_SESSION *session,
* 40 = packet_type(1) + username_len(4) + service_len(4) +
* service(14)"ssh-connection" + method_len(4) + method(8)"password" +
* chgpwdbool(1) + password_len(4) */
if(username_len > UINT32_MAX - 40) {
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"username_len out of bounds");
}
session->userauth_pswd_data_len = username_len + 40;
session->userauth_pswd_data0 =
@ -447,7 +458,7 @@ password_response:
}
/* basic data_len + newpw_len(4) */
if(username_len + password_len + 44 <= UINT_MAX) {
if(username_len <= UINT32_MAX - password_len - 44) {
session->userauth_pswd_data_len =
username_len + password_len + 44;
s = session->userauth_pswd_data =