File libssh2_org-CVE-2019-3859.patch of Package libssh2_org.13039
Index: libssh2-1.8.0/src/channel.c
===================================================================
--- libssh2-1.8.0.orig/src/channel.c
+++ libssh2-1.8.0/src/channel.c
@@ -238,7 +238,20 @@ _libssh2_channel_open(LIBSSH2_SESSION *
goto channel_error;
}
+ if(session->open_data_len < 1) {
+ _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "Unexpected packet size");
+ goto channel_error;
+ }
+
if (session->open_data[0] == SSH_MSG_CHANNEL_OPEN_CONFIRMATION) {
+
+ if(session->open_data_len < 17) {
+ _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "Unexpected packet size");
+ goto channel_error;
+ }
+
session->open_channel->remote.id =
_libssh2_ntohu32(session->open_data + 5);
session->open_channel->local.window_size =
@@ -518,7 +531,7 @@ channel_forward_listen(LIBSSH2_SESSION *
if (rc == LIBSSH2_ERROR_EAGAIN) {
_libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block");
return NULL;
- } else if (rc) {
+ } else if (rc || data_len < 1) {
_libssh2_error(session, LIBSSH2_ERROR_PROTO, "Unknown");
session->fwdLstn_state = libssh2_NB_state_idle;
return NULL;
@@ -855,6 +868,11 @@ static int channel_setenv(LIBSSH2_CHANNE
channel->setenv_state = libssh2_NB_state_idle;
return rc;
}
+ else if(data_len < 1) {
+ channel->setenv_state = libssh2_NB_state_idle;
+ return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "Unexpected packet size");
+ }
if (data[0] == SSH_MSG_CHANNEL_SUCCESS) {
LIBSSH2_FREE(session, data);
@@ -971,7 +989,7 @@ static int channel_request_pty(LIBSSH2_C
&channel->reqPTY_packet_requirev_state);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc) {
+ } else if (rc || data_len < 1) {
channel->reqPTY_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
"Failed to require the PTY package");
@@ -1197,7 +1215,7 @@ channel_x11_req(LIBSSH2_CHANNEL *channel
&channel->reqX11_packet_requirev_state);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc) {
+ } else if (rc || data_len < 1) {
channel->reqX11_state = libssh2_NB_state_idle;
return _libssh2_error(session, rc,
"waiting for x11-req response packet");
@@ -1324,7 +1342,7 @@ _libssh2_channel_process_startup(LIBSSH2
&channel->process_packet_requirev_state);
if (rc == LIBSSH2_ERROR_EAGAIN) {
return rc;
- } else if (rc) {
+ } else if (rc || data_len < 1) {
channel->process_state = libssh2_NB_state_end;
return _libssh2_error(session, rc,
"Failed waiting for channel success");
Index: libssh2-1.8.0/src/kex.c
===================================================================
--- libssh2-1.8.0.orig/src/kex.c
+++ libssh2-1.8.0/src/kex.c
@@ -228,11 +228,23 @@ static int diffie_hellman_sha1(LIBSSH2_S
}
/* Parse KEXDH_REPLY */
+ if(exchange_state->s_packet_len < 5) {
+ ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "Unexpected packet length");
+ goto clean_exit;
+ }
+
exchange_state->s = exchange_state->s_packet + 1;
session->server_hostkey_len = _libssh2_ntohu32(exchange_state->s);
exchange_state->s += 4;
+ if(session->server_hostkey_len > exchange_state->s_packet_len - 5) {
+ ret = _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
+ "Host key length out of bounds");
+ goto clean_exit;
+ }
+
if (session->server_hostkey)
LIBSSH2_FREE(session, session->server_hostkey);
@@ -848,11 +860,23 @@ static int diffie_hellman_sha256(LIBSSH2
}
/* Parse KEXDH_REPLY */
+ if(exchange_state->s_packet_len < 5) {
+ ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "Unexpected packet length");
+ goto clean_exit;
+ }
+
exchange_state->s = exchange_state->s_packet + 1;
session->server_hostkey_len = _libssh2_ntohu32(exchange_state->s);
exchange_state->s += 4;
+ if(session->server_hostkey_len > exchange_state->s_packet_len - 5) {
+ ret = _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
+ "Host key length out of bounds");
+ goto clean_exit;
+ }
+
if (session->server_hostkey)
LIBSSH2_FREE(session, session->server_hostkey);
Index: libssh2-1.8.0/src/session.c
===================================================================
--- libssh2-1.8.0.orig/src/session.c
+++ libssh2-1.8.0/src/session.c
@@ -765,6 +765,11 @@ session_startup(LIBSSH2_SESSION *session
if (rc)
return rc;
+ if(session->startup_data_len < 5) {
+ return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "Unexpected packet length");
+ }
+
session->startup_service_length =
_libssh2_ntohu32(session->startup_data + 1);
Index: libssh2-1.8.0/src/userauth.c
===================================================================
--- libssh2-1.8.0.orig/src/userauth.c
+++ libssh2-1.8.0/src/userauth.c
@@ -107,7 +107,7 @@ static char *userauth_list(LIBSSH2_SESSI
LIBSSH2_FREE(session, session->userauth_list_data);
session->userauth_list_data = NULL;
- if (rc) {
+ if (rc || (session->userauth_list_data_len < 1)) {
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
"Unable to send userauth-none request");
session->userauth_list_state = libssh2_NB_state_idle;
@@ -143,8 +143,20 @@ static char *userauth_list(LIBSSH2_SESSI
return NULL;
}
- methods_len = _libssh2_ntohu32(session->userauth_list_data + 1);
+ if(session->userauth_list_data_len < 5) {
+ LIBSSH2_FREE(session, session->userauth_list_data);
+ session->userauth_list_data = NULL;
+ _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "Unexpected packet size");
+ return NULL;
+ }
+ methods_len = _libssh2_ntohu32(session->userauth_list_data + 1);
+ if(methods_len >= session->userauth_list_data_len - 5) {
+ _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
+ "Unexpected userauth list size");
+ return NULL;
+ }
/* Do note that the memory areas overlap! */
memmove(session->userauth_list_data, session->userauth_list_data + 5,
methods_len);
@@ -285,6 +297,11 @@ userauth_password(LIBSSH2_SESSION *sessi
return _libssh2_error(session, rc,
"Waiting for password response");
}
+ else if(session->userauth_pswd_data_len < 1) {
+ session->userauth_pswd_state = libssh2_NB_state_idle;
+ return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "Unexpected packet size");
+ }
if (session->userauth_pswd_data[0] == SSH_MSG_USERAUTH_SUCCESS) {
_libssh2_debug(session, LIBSSH2_TRACE_AUTH,
@@ -312,6 +329,12 @@ userauth_password(LIBSSH2_SESSION *sessi
session->userauth_pswd_state = libssh2_NB_state_sent1;
}
+ if(session->userauth_pswd_data_len < 1) {
+ session->userauth_pswd_state = libssh2_NB_state_idle;
+ return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
+ "Unexpected packet size");
+ }
+
if ((session->userauth_pswd_data[0] ==
SSH_MSG_USERAUTH_PASSWD_CHANGEREQ)
|| (session->userauth_pswd_data0 ==
@@ -976,7 +999,7 @@ userauth_hostbased_fromfile(LIBSSH2_SESS
}
session->userauth_host_state = libssh2_NB_state_idle;
- if (rc) {
+ if (rc || data_len < 1) {
return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED,
"Auth failed");
}
@@ -1149,7 +1172,7 @@ _libssh2_userauth_publickey(LIBSSH2_SESS
NULL, 0);
if (rc == LIBSSH2_ERROR_EAGAIN)
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block");
- else if (rc) {
+ else if (rc || (session->userauth_pblc_data_len < 1)) {
LIBSSH2_FREE(session, session->userauth_pblc_packet);
session->userauth_pblc_packet = NULL;
LIBSSH2_FREE(session, session->userauth_pblc_method);
@@ -1332,7 +1355,7 @@ _libssh2_userauth_publickey(LIBSSH2_SESS
if (rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block requesting userauth list");
- } else if (rc) {
+ } else if (rc || session->userauth_pblc_data_len < 1) {
session->userauth_pblc_state = libssh2_NB_state_idle;
return _libssh2_error(session, LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED,
"Waiting for publickey USERAUTH response");
@@ -1654,7 +1677,7 @@ userauth_keyboard_interactive(LIBSSH2_SE
if (rc == LIBSSH2_ERROR_EAGAIN) {
return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
"Would block");
- } else if (rc) {
+ } else if (rc || session->userauth_kybd_data_len < 1) {
session->userauth_kybd_state = libssh2_NB_state_idle;
return _libssh2_error(session,
LIBSSH2_ERROR_AUTHENTICATION_FAILED,