Control: tags 924965 + pending

Dear maintainer,

I've prepared an NMU for libssh2 (versioned as 1.8.0-2.1) and
uploaded it to DELAYED/5. Please feel free to tell me if I
should delay it longer.

Regards,
Salvatore
diff -Nru libssh2-1.8.0/debian/changelog libssh2-1.8.0/debian/changelog
--- libssh2-1.8.0/debian/changelog	2018-06-23 21:45:38.000000000 +0200
+++ libssh2-1.8.0/debian/changelog	2019-03-31 16:06:20.000000000 +0200
@@ -1,3 +1,29 @@
+libssh2 (1.8.0-2.1) unstable; urgency=high
+
+  * Non-maintainer upload.
+  * Possible integer overflow in transport read allows out-of-bounds write
+    (CVE-2019-3855) (Closes: #924965)
+  * Possible integer overflow in keyboard interactive handling allows
+    out-of-bounds write (CVE-2019-3856) (Closes: #924965)
+  * Possible integer overflow leading to zero-byte allocation and
+    out-of-bounds write (CVE-2019-3857) (Closes: #924965)
+  * Possible zero-byte allocation leading to an out-of-bounds read
+    (CVE-2019-3858) (Closes: #924965)
+  * Out-of-bounds reads with specially crafted payloads due to unchecked use
+    of _libssh2_packet_require and _libssh2_packet_requirev (CVE-2019-3859)
+    (Closes: #924965)
+  * Out-of-bounds reads with specially crafted SFTP packets (CVE-2019-3860)
+    (Closes: #924965)
+  * Out-of-bounds reads with specially crafted SSH packets (CVE-2019-3861)
+    (Closes: #924965)
+  * Out-of-bounds memory comparison (CVE-2019-3862) (Closes: #924965)
+  * Integer overflow in user authenicate keyboard interactive allows
+    out-of-bounds writes (CVE-2019-3863) (Closes: #924965)
+  * Fixed misapplied patch for user auth.
+  * moved MAX size declarations
+
+ -- Salvatore Bonaccorso <car...@debian.org>  Sun, 31 Mar 2019 16:06:20 +0200
+
 libssh2 (1.8.0-2) unstable; urgency=low
 
   * Add missing zlib1g-dev dependency (Closes: #900558).
diff -Nru libssh2-1.8.0/debian/patches/CVE-2019-3855.patch libssh2-1.8.0/debian/patches/CVE-2019-3855.patch
--- libssh2-1.8.0/debian/patches/CVE-2019-3855.patch	1970-01-01 01:00:00.000000000 +0100
+++ libssh2-1.8.0/debian/patches/CVE-2019-3855.patch	2019-03-31 16:06:20.000000000 +0200
@@ -0,0 +1,22 @@
+Description: Possible integer overflow in transport read allows out-of-bounds write
+Origin: upstream, https://libssh2.org/1.8.0-CVE/CVE-2019-3855.patch
+Bug-Debian: https://bugs.debian.org/924965
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-3855
+Forwarded: not-needed
+Last-Update: 2019-03-30
+
+--- a/src/transport.c
++++ b/src/transport.c
+@@ -438,6 +438,12 @@ int _libssh2_transport_read(LIBSSH2_SESS
+                 return LIBSSH2_ERROR_DECRYPT;
+ 
+             p->padding_length = block[4];
++            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 is the number of bytes following the initial
+                (5 bytes) packet length and padding length fields */
diff -Nru libssh2-1.8.0/debian/patches/CVE-2019-3856.patch libssh2-1.8.0/debian/patches/CVE-2019-3856.patch
--- libssh2-1.8.0/debian/patches/CVE-2019-3856.patch	1970-01-01 01:00:00.000000000 +0100
+++ libssh2-1.8.0/debian/patches/CVE-2019-3856.patch	2019-03-31 16:06:20.000000000 +0200
@@ -0,0 +1,23 @@
+Description: Possible integer overflow in keyboard interactive handling allows out-of-bounds write
+Origin: upstream, https://libssh2.org/1.8.0-CVE/CVE-2019-3856.patch
+Bug-Debian: https://bugs.debian.org/924965
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-3856
+Forwarded: not-needed
+Last-Update: 2019-03-30
+
+--- a/src/userauth.c
++++ b/src/userauth.c
+@@ -1734,6 +1734,13 @@ userauth_keyboard_interactive(LIBSSH2_SE
+             /* int       num-prompts */
+             session->userauth_kybd_num_prompts = _libssh2_ntohu32(s);
+             s += 4;
++            if(session->userauth_kybd_num_prompts && 
++               session->userauth_kybd_num_prompts > 100) {
++               _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
++                              "Too many replies for "
++                              "keyboard-interactive prompts");
++               goto cleanup;
++            }
+ 
+             if(session->userauth_kybd_num_prompts) {
+                 session->userauth_kybd_prompts =
diff -Nru libssh2-1.8.0/debian/patches/CVE-2019-3857.patch libssh2-1.8.0/debian/patches/CVE-2019-3857.patch
--- libssh2-1.8.0/debian/patches/CVE-2019-3857.patch	1970-01-01 01:00:00.000000000 +0100
+++ libssh2-1.8.0/debian/patches/CVE-2019-3857.patch	2019-03-31 16:06:20.000000000 +0200
@@ -0,0 +1,48 @@
+Description: Possible integer overflow leading to zero-byte allocation and out-of-bounds write
+Origin: upstream, https://libssh2.org/1.8.0-CVE/CVE-2019-3857.patch
+Bug-Debian: https://bugs.debian.org/924965
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-3857
+Forwarded: not-needed
+Last-Update: 2019-03-30
+
+--- a/include/libssh2.h
++++ b/include/libssh2.h
+@@ -145,6 +145,18 @@ typedef int libssh2_socket_t;
+ #define LIBSSH2_INVALID_SOCKET -1
+ #endif /* WIN32 */
+ 
++#ifndef SIZE_MAX
++#if _WIN64
++#define SIZE_MAX 0xFFFFFFFFFFFFFFFF
++#else
++#define SIZE_MAX 0xFFFFFFFF
++#endif
++#endif
++
++#ifndef UINT_MAX
++#define UINT_MAX 0xFFFFFFFF
++#endif
++
+ /*
+  * Determine whether there is small or large file support on windows.
+  */
+--- a/src/packet.c
++++ b/src/packet.c
+@@ -815,8 +815,15 @@ _libssh2_packet_add(LIBSSH2_SESSION * se
+                         /* set signal name (without SIG prefix) */
+                         uint32_t namelen =
+                             _libssh2_ntohu32(data + 9 + sizeof("exit-signal"));
+-                        channelp->exit_signal =
+-                            LIBSSH2_ALLOC(session, namelen + 1);
++
++                        if(namelen <= UINT_MAX - 1) {
++                            channelp->exit_signal =
++                                LIBSSH2_ALLOC(session, namelen + 1);
++                        }
++                        else {
++                            channelp->exit_signal = NULL;
++                        }
++
+                         if (!channelp->exit_signal)
+                             rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
+                                                 "memory for signal name");
diff -Nru libssh2-1.8.0/debian/patches/CVE-2019-3858.patch libssh2-1.8.0/debian/patches/CVE-2019-3858.patch
--- libssh2-1.8.0/debian/patches/CVE-2019-3858.patch	1970-01-01 01:00:00.000000000 +0100
+++ libssh2-1.8.0/debian/patches/CVE-2019-3858.patch	2019-03-31 16:06:20.000000000 +0200
@@ -0,0 +1,20 @@
+Description: Possible zero-byte allocation leading to an out-of-bounds read 
+Origin: upstream, https://libssh2.org/1.8.0-CVE/CVE-2019-3858.patch
+Bug-Debian: https://bugs.debian.org/924965
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-3858
+Forwarded: not-needed
+Last-Update: 2019-03-30
+
+--- a/src/sftp.c
++++ b/src/sftp.c
+@@ -345,6 +345,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",
diff -Nru libssh2-1.8.0/debian/patches/CVE-2019-3859.patch libssh2-1.8.0/debian/patches/CVE-2019-3859.patch
--- libssh2-1.8.0/debian/patches/CVE-2019-3859.patch	1970-01-01 01:00:00.000000000 +0100
+++ libssh2-1.8.0/debian/patches/CVE-2019-3859.patch	2019-03-31 16:06:20.000000000 +0200
@@ -0,0 +1,236 @@
+Description: Out-of-bounds reads with specially crafted payloads due to unchecked use of _libssh2_packet_require and _libssh2_packet_requirev
+Origin: upstream, https://libssh2.org/1.8.0-CVE/CVE-2019-3859.patch
+Bug-Debian: https://bugs.debian.org/924965
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-3859
+Forwarded: not-needed
+Last-Update: 2019-03-30
+
+--- a/src/channel.c
++++ b/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");
+--- a/src/kex.c
++++ b/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);
+ 
+--- a/src/session.c
++++ b/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);
+ 
+--- a/src/userauth.c
++++ b/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,
diff -Nru libssh2-1.8.0/debian/patches/CVE-2019-3860.patch libssh2-1.8.0/debian/patches/CVE-2019-3860.patch
--- libssh2-1.8.0/debian/patches/CVE-2019-3860.patch	1970-01-01 01:00:00.000000000 +0100
+++ libssh2-1.8.0/debian/patches/CVE-2019-3860.patch	2019-03-31 16:06:20.000000000 +0200
@@ -0,0 +1,574 @@
+Description: Out-of-bounds reads with specially crafted SFTP packets
+Origin: upstream, https://libssh2.org/1.8.0-CVE/CVE-2019-3860.patch
+Bug-Debian: https://bugs.debian.org/924965
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-3860
+Forwarded: not-needed
+Last-Update: 2019-03-30
+
+--- a/src/sftp.c
++++ b/src/sftp.c
+@@ -508,11 +508,15 @@ sftp_packet_ask(LIBSSH2_SFTP *sftp, unsi
+ 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);
+ 
+@@ -520,6 +524,11 @@ sftp_packet_require(LIBSSH2_SFTP *sftp,
+         /* 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;
+     }
+ 
+@@ -533,6 +542,11 @@ sftp_packet_require(LIBSSH2_SFTP *sftp,
+             /* 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;
+         }
+     }
+@@ -548,11 +562,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);
+@@ -566,6 +584,11 @@ sftp_packet_requirev(LIBSSH2_SFTP *sftp,
+                  * the timeout is not active
+                  */
+                 sftp->requirev_start = 0;
++
++                if (*data_len < required_size) {
++                    return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
++                }
++
+                 return LIBSSH2_ERROR_NONE;
+             }
+         }
+@@ -640,36 +663,65 @@ sftp_attr2bin(unsigned char *p, const LI
+ /* 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);
+@@ -839,18 +891,23 @@ static LIBSSH2_SFTP *sftp_init(LIBSSH2_S
+     }
+ 
+     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;
+     }
+ 
+@@ -1116,12 +1173,20 @@ sftp_open(LIBSSH2_SFTP *sftp, const char
+             { 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");
+@@ -1152,12 +1217,20 @@ sftp_open(LIBSSH2_SFTP *sftp, const char
+                 /* 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;
+@@ -1484,15 +1557,21 @@ static ssize_t sftp_read(LIBSSH2_SFTP_HA
+             }
+ 
+             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;
+             }
+@@ -1702,7 +1781,7 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP
+             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:
+@@ -1757,9 +1836,16 @@ static ssize_t sftp_readdir(LIBSSH2_SFTP
+ 
+     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,
+@@ -1985,8 +2071,15 @@ static ssize_t sftp_write(LIBSSH2_SFTP_H
+ 
+             /* 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;
+@@ -2128,10 +2221,18 @@ static int sftp_fsync(LIBSSH2_SFTP_HANDL
+     }
+ 
+     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");
+@@ -2231,9 +2332,16 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDL
+ 
+     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,
+@@ -2256,7 +2364,12 @@ static int sftp_fstat(LIBSSH2_SFTP_HANDL
+         }
+     }
+ 
+-    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;
+@@ -2433,11 +2546,19 @@ sftp_close_handle(LIBSSH2_SFTP_HANDLE *h
+     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");
+         }
+@@ -2551,10 +2672,17 @@ static int sftp_unlink(LIBSSH2_SFTP *sft
+ 
+     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,
+@@ -2662,10 +2790,18 @@ static int sftp_rename(LIBSSH2_SFTP *sft
+ 
+     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");
+@@ -2787,11 +2923,19 @@ static int sftp_fstatvfs(LIBSSH2_SFTP_HA
+     }
+ 
+     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");
+@@ -2914,10 +3058,18 @@ static int sftp_statvfs(LIBSSH2_SFTP *sf
+     }
+ 
+     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");
+@@ -3044,10 +3196,18 @@ static int sftp_mkdir(LIBSSH2_SFTP *sftp
+     }
+ 
+     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");
+@@ -3138,10 +3298,18 @@ static int sftp_rmdir(LIBSSH2_SFTP *sftp
+     }
+ 
+     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");
+@@ -3251,9 +3419,16 @@ static int sftp_stat(LIBSSH2_SFTP *sftp,
+     }
+ 
+     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,
+@@ -3277,7 +3452,12 @@ static int sftp_stat(LIBSSH2_SFTP *sftp,
+     }
+ 
+     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;
+@@ -3382,9 +3562,16 @@ static int sftp_symlink(LIBSSH2_SFTP *sf
+ 
+     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,
+@@ -3414,6 +3601,14 @@ static int sftp_symlink(LIBSSH2_SFTP *sf
+                               "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) {
diff -Nru libssh2-1.8.0/debian/patches/CVE-2019-3861.patch libssh2-1.8.0/debian/patches/CVE-2019-3861.patch
--- libssh2-1.8.0/debian/patches/CVE-2019-3861.patch	1970-01-01 01:00:00.000000000 +0100
+++ libssh2-1.8.0/debian/patches/CVE-2019-3861.patch	2019-03-31 16:06:20.000000000 +0200
@@ -0,0 +1,19 @@
+Description: Out-of-bounds reads with specially crafted SSH packets
+Origin: upstream, https://libssh2.org/1.8.0-CVE/CVE-2019-3861.patch
+Bug-Debian: https://bugs.debian.org/924965
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-3861
+Forwarded: not-needed
+Last-Update: 2019-03-30
+
+--- a/src/transport.c
++++ b/src/transport.c
+@@ -438,6 +438,9 @@ int _libssh2_transport_read(LIBSSH2_SESS
+                 return LIBSSH2_ERROR_DECRYPT;
+ 
+             p->padding_length = block[4];
++            if ( p->padding_length > p->packet_length - 1 ) {
++                return LIBSSH2_ERROR_DECRYPT;
++            }
+             if(p->packet_length < 1) {
+                 return LIBSSH2_ERROR_DECRYPT;
+             }
diff -Nru libssh2-1.8.0/debian/patches/CVE-2019-3862.patch libssh2-1.8.0/debian/patches/CVE-2019-3862.patch
--- libssh2-1.8.0/debian/patches/CVE-2019-3862.patch	1970-01-01 01:00:00.000000000 +0100
+++ libssh2-1.8.0/debian/patches/CVE-2019-3862.patch	2019-03-31 16:06:20.000000000 +0200
@@ -0,0 +1,65 @@
+Description: Out-of-bounds memory comparison
+Origin: upstream, https://libssh2.org/1.8.0-CVE/CVE-2019-3862.patch
+Bug-Debian: https://bugs.debian.org/924965
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-3862
+Forwarded: not-needed
+Last-Update: 2019-03-30
+
+--- a/src/packet.c
++++ b/src/packet.c
+@@ -775,8 +775,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * se
+                 uint32_t len = _libssh2_ntohu32(data + 5);
+                 unsigned char want_reply = 1;
+ 
+-                if(len < (datalen - 10))
+-                    want_reply = data[9 + len];
++                if((len + 9) < datalen)
++                    want_reply = data[len + 9];
+ 
+                 _libssh2_debug(session,
+                                LIBSSH2_TRACE_CONN,
+@@ -784,6 +784,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * se
+                                channel, len, data + 9, want_reply);
+ 
+                 if (len == sizeof("exit-status") - 1
++                    && (sizeof("exit-status") - 1 + 9) <= datalen
+                     && !memcmp("exit-status", data + 9,
+                                sizeof("exit-status") - 1)) {
+ 
+@@ -792,7 +793,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * se
+                         channelp =
+                             _libssh2_channel_locate(session, channel);
+ 
+-                    if (channelp) {
++                    if (channelp && (sizeof("exit-status") + 13) <= datalen) {
+                         channelp->exit_status =
+                             _libssh2_ntohu32(data + 9 + sizeof("exit-status"));
+                         _libssh2_debug(session, LIBSSH2_TRACE_CONN,
+@@ -805,13 +806,14 @@ _libssh2_packet_add(LIBSSH2_SESSION * se
+ 
+                 }
+                 else if (len == sizeof("exit-signal") - 1
++                         && (sizeof("exit-signal") - 1 + 9) <= datalen
+                          && !memcmp("exit-signal", data + 9,
+                                     sizeof("exit-signal") - 1)) {
+                     /* command terminated due to signal */
+                     if(datalen >= 20)
+                         channelp = _libssh2_channel_locate(session, channel);
+ 
+-                    if (channelp) {
++                    if (channelp && (sizeof("exit-signal") + 13) <= datalen) {
+                         /* set signal name (without SIG prefix) */
+                         uint32_t namelen =
+                             _libssh2_ntohu32(data + 9 + sizeof("exit-signal"));
+@@ -827,9 +829,9 @@ _libssh2_packet_add(LIBSSH2_SESSION * se
+                         if (!channelp->exit_signal)
+                             rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
+                                                 "memory for signal name");
+-                        else {
++                        else if ((sizeof("exit-signal") + 13 + namelen <= datalen)) {
+                             memcpy(channelp->exit_signal,
+-                                   data + 13 + sizeof("exit_signal"), namelen);
++                                   data + 13 + sizeof("exit-signal"), namelen);
+                             channelp->exit_signal[namelen] = '\0';
+                             /* TODO: save error message and language tag */
+                             _libssh2_debug(session, LIBSSH2_TRACE_CONN,
diff -Nru libssh2-1.8.0/debian/patches/CVE-2019-3863.patch libssh2-1.8.0/debian/patches/CVE-2019-3863.patch
--- libssh2-1.8.0/debian/patches/CVE-2019-3863.patch	1970-01-01 01:00:00.000000000 +0100
+++ libssh2-1.8.0/debian/patches/CVE-2019-3863.patch	2019-03-31 16:06:20.000000000 +0200
@@ -0,0 +1,29 @@
+Description: Integer overflow in user authenicate keyboard interactive allows out-of-bounds writes
+Origin: upstream, https://libssh2.org/1.8.0-CVE/CVE-2019-3863.patch
+Bug-Debian: https://bugs.debian.org/924965
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-3863
+Forwarded: not-needed
+Last-Update: 2019-03-30
+
+--- a/src/userauth.c
++++ b/src/userauth.c
+@@ -1831,8 +1831,17 @@ userauth_keyboard_interactive(LIBSSH2_SE
+ 
+             for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
+                 /* string    response[1] (ISO-10646 UTF-8) */
+-                session->userauth_kybd_packet_len +=
+-                    4 + session->userauth_kybd_responses[i].length;
++                 if(session->userauth_kybd_responses[i].length <=
++                   (SIZE_MAX - 4 - session->userauth_kybd_packet_len) ) {
++                    session->userauth_kybd_packet_len +=
++                        4 + session->userauth_kybd_responses[i].length;
++                }
++                else {
++                    _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
++                                   "Unable to allocate memory for keyboard-"
++                                   "interactive response packet");
++                    goto cleanup;
++                }
+             }
+ 
+             /* A new userauth_kybd_data area is to be allocated, free the
diff -Nru libssh2-1.8.0/debian/patches/Fixed-misapplied-patch-327.patch libssh2-1.8.0/debian/patches/Fixed-misapplied-patch-327.patch
--- libssh2-1.8.0/debian/patches/Fixed-misapplied-patch-327.patch	1970-01-01 01:00:00.000000000 +0100
+++ libssh2-1.8.0/debian/patches/Fixed-misapplied-patch-327.patch	2019-03-31 16:06:20.000000000 +0200
@@ -0,0 +1,54 @@
+From: Will Cosgrove <w...@panic.com>
+Date: Tue, 19 Mar 2019 09:38:16 -0700
+Subject: Fixed misapplied patch (#327)
+Origin: https://github.com/libssh2/libssh2/commit/165f05ef01a95538b426cc8c90da8accfaa20d01
+Bug: https://github.com/libssh2/libssh2/pull/327
+
+Fixes for user auth
+---
+ src/userauth.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/userauth.c b/src/userauth.c
+index ed804629d251..c02d81d0ea1d 100644
+--- a/src/userauth.c
++++ b/src/userauth.c
+@@ -107,7 +107,7 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
+         LIBSSH2_FREE(session, session->userauth_list_data);
+         session->userauth_list_data = NULL;
+ 
+-        if (rc || (session->userauth_list_data_len < 1)) {
++        if (rc) {
+             _libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
+                            "Unable to send userauth-none request");
+             session->userauth_list_state = libssh2_NB_state_idle;
+@@ -127,7 +127,7 @@ static char *userauth_list(LIBSSH2_SESSION *session, const char *username,
+             _libssh2_error(session, LIBSSH2_ERROR_EAGAIN,
+                            "Would block requesting userauth list");
+             return NULL;
+-        } else if (rc) {
++        } else if (rc || (session->userauth_list_data_len < 1)) {
+             _libssh2_error(session, rc, "Failed getting response");
+             session->userauth_list_state = libssh2_NB_state_idle;
+             return NULL;
+@@ -1172,7 +1172,7 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
+                                      NULL, 0);
+         if (rc == LIBSSH2_ERROR_EAGAIN)
+             return _libssh2_error(session, LIBSSH2_ERROR_EAGAIN, "Would block");
+-        else if (rc || (session->userauth_pblc_data_len < 1)) {
++        else if (rc) {
+             LIBSSH2_FREE(session, session->userauth_pblc_packet);
+             session->userauth_pblc_packet = NULL;
+             LIBSSH2_FREE(session, session->userauth_pblc_method);
+@@ -1195,7 +1195,7 @@ _libssh2_userauth_publickey(LIBSSH2_SESSION *session,
+         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);
+-- 
+2.11.0
+
diff -Nru libssh2-1.8.0/debian/patches/moved-MAX-size-declarations-330.patch libssh2-1.8.0/debian/patches/moved-MAX-size-declarations-330.patch
--- libssh2-1.8.0/debian/patches/moved-MAX-size-declarations-330.patch	1970-01-01 01:00:00.000000000 +0100
+++ libssh2-1.8.0/debian/patches/moved-MAX-size-declarations-330.patch	2019-03-31 16:06:20.000000000 +0200
@@ -0,0 +1,60 @@
+From: Will Cosgrove <w...@panic.com>
+Date: Wed, 20 Mar 2019 08:44:37 -0700
+Subject: moved MAX size declarations #330
+Origin: https://github.com/libssh2/libssh2/commit/57e846c8c90cf29e21b927a636593ba5cfb81334
+Bug: https://github.com/libssh2/libssh2/issues/330
+
+---
+ include/libssh2.h  | 12 ------------
+ src/libssh2_priv.h | 12 ++++++++++++
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/include/libssh2.h b/include/libssh2.h
+index f4bae24bc511..9ef9ff11dca7 100644
+--- a/include/libssh2.h
++++ b/include/libssh2.h
+@@ -145,18 +145,6 @@ typedef int libssh2_socket_t;
+ #define LIBSSH2_INVALID_SOCKET -1
+ #endif /* WIN32 */
+ 
+-#ifndef SIZE_MAX
+-#if _WIN64
+-#define SIZE_MAX 0xFFFFFFFFFFFFFFFF
+-#else
+-#define SIZE_MAX 0xFFFFFFFF
+-#endif
+-#endif
+-
+-#ifndef UINT_MAX
+-#define UINT_MAX 0xFFFFFFFF
+-#endif
+-
+ /*
+  * Determine whether there is small or large file support on windows.
+  */
+diff --git a/src/libssh2_priv.h b/src/libssh2_priv.h
+index b4296a221a19..bb5d1a50a10f 100644
+--- a/src/libssh2_priv.h
++++ b/src/libssh2_priv.h
+@@ -146,6 +146,18 @@ static inline int writev(int sock, struct iovec *iov, int nvecs)
+ 
+ #endif
+ 
++#ifndef SIZE_MAX
++#if _WIN64
++#define SIZE_MAX 0xFFFFFFFFFFFFFFFF
++#else
++#define SIZE_MAX 0xFFFFFFFF
++#endif
++#endif
++
++#ifndef UINT_MAX
++#define UINT_MAX 0xFFFFFFFF
++#endif
++
+ /* RFC4253 section 6.1 Maximum Packet Length says:
+  *
+  * "All implementations MUST be able to process packets with
+-- 
+2.11.0
+
diff -Nru libssh2-1.8.0/debian/patches/series libssh2-1.8.0/debian/patches/series
--- libssh2-1.8.0/debian/patches/series	2018-06-23 21:45:38.000000000 +0200
+++ libssh2-1.8.0/debian/patches/series	2019-03-31 16:06:20.000000000 +0200
@@ -1,3 +1,14 @@
 0001-Add-lgpg-error-to-.pc-to-facilitate-static-linking.patch
 0001-Do-not-expose-private-libraries-nor-link-flags-to-us.patch
 ced924b78a40126606797ef57a74066eb3b4b83f.patch
+CVE-2019-3855.patch
+CVE-2019-3856.patch
+CVE-2019-3857.patch
+CVE-2019-3858.patch
+CVE-2019-3859.patch
+CVE-2019-3860.patch
+CVE-2019-3861.patch
+CVE-2019-3862.patch
+CVE-2019-3863.patch
+Fixed-misapplied-patch-327.patch
+moved-MAX-size-declarations-330.patch

Reply via email to