|
|
e5bfac |
From 0e4e9825e637a15707a910539d71fe65e7e12d7b Mon Sep 17 00:00:00 2001
|
|
|
e5bfac |
From: Kamil Dudka <kdudka@redhat.com>
|
|
|
e5bfac |
Date: Tue, 19 Mar 2019 13:45:22 +0100
|
|
|
e5bfac |
Subject: [PATCH] Resolves: CVE-2019-3862 - fix out-of-bounds memory comparison
|
|
|
e5bfac |
|
|
|
e5bfac |
... with specially crafted message channel request
|
|
|
e5bfac |
|
|
|
e5bfac |
Upstream-Patch: https://libssh2.org/1.8.0-CVE/CVE-2019-3862.patch
|
|
|
e5bfac |
---
|
|
|
e5bfac |
src/packet.c | 14 ++++++++------
|
|
|
e5bfac |
1 file changed, 8 insertions(+), 6 deletions(-)
|
|
|
e5bfac |
|
|
|
e5bfac |
diff --git a/src/packet.c b/src/packet.c
|
|
|
e5bfac |
index aa10633..c950b5d 100644
|
|
|
e5bfac |
--- a/src/packet.c
|
|
|
e5bfac |
+++ b/src/packet.c
|
|
|
d780b0 |
@@ -775,8 +775,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|
|
e5bfac |
uint32_t len = _libssh2_ntohu32(data + 5);
|
|
|
e5bfac |
unsigned char want_reply = 1;
|
|
|
e5bfac |
|
|
|
e5bfac |
- if(len < (datalen - 10))
|
|
|
e5bfac |
- want_reply = data[9 + len];
|
|
|
e5bfac |
+ if((len + 9) < datalen)
|
|
|
e5bfac |
+ want_reply = data[len + 9];
|
|
|
e5bfac |
|
|
|
e5bfac |
_libssh2_debug(session,
|
|
|
e5bfac |
LIBSSH2_TRACE_CONN,
|
|
|
d780b0 |
@@ -784,6 +784,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|
|
e5bfac |
channel, len, data + 9, want_reply);
|
|
|
e5bfac |
|
|
|
e5bfac |
if (len == sizeof("exit-status") - 1
|
|
|
e5bfac |
+ && (sizeof("exit-status") - 1 + 9) <= datalen
|
|
|
e5bfac |
&& !memcmp("exit-status", data + 9,
|
|
|
e5bfac |
sizeof("exit-status") - 1)) {
|
|
|
e5bfac |
|
|
|
d780b0 |
@@ -792,7 +793,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|
|
e5bfac |
channelp =
|
|
|
e5bfac |
_libssh2_channel_locate(session, channel);
|
|
|
e5bfac |
|
|
|
e5bfac |
- if (channelp) {
|
|
|
e5bfac |
+ if (channelp && (sizeof("exit-status") + 13) <= datalen) {
|
|
|
e5bfac |
channelp->exit_status =
|
|
|
e5bfac |
_libssh2_ntohu32(data + 9 + sizeof("exit-status"));
|
|
|
e5bfac |
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
|
|
d780b0 |
@@ -805,13 +806,14 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|
|
e5bfac |
|
|
|
e5bfac |
}
|
|
|
e5bfac |
else if (len == sizeof("exit-signal") - 1
|
|
|
e5bfac |
+ && (sizeof("exit-signal") - 1 + 9) <= datalen
|
|
|
e5bfac |
&& !memcmp("exit-signal", data + 9,
|
|
|
e5bfac |
sizeof("exit-signal") - 1)) {
|
|
|
e5bfac |
/* command terminated due to signal */
|
|
|
e5bfac |
if(datalen >= 20)
|
|
|
e5bfac |
channelp = _libssh2_channel_locate(session, channel);
|
|
|
e5bfac |
|
|
|
e5bfac |
- if (channelp) {
|
|
|
e5bfac |
+ if (channelp && (sizeof("exit-signal") + 13) <= datalen) {
|
|
|
e5bfac |
/* set signal name (without SIG prefix) */
|
|
|
e5bfac |
uint32_t namelen =
|
|
|
e5bfac |
_libssh2_ntohu32(data + 9 + sizeof("exit-signal"));
|
|
|
d780b0 |
@@ -827,9 +829,9 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
|
|
e5bfac |
if (!channelp->exit_signal)
|
|
|
e5bfac |
rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
|
|
e5bfac |
"memory for signal name");
|
|
|
e5bfac |
- else {
|
|
|
e5bfac |
+ else if ((sizeof("exit-signal") + 13 + namelen <= datalen)) {
|
|
|
e5bfac |
memcpy(channelp->exit_signal,
|
|
|
e5bfac |
- data + 13 + sizeof("exit_signal"), namelen);
|
|
|
e5bfac |
+ data + 13 + sizeof("exit-signal"), namelen);
|
|
|
e5bfac |
channelp->exit_signal[namelen] = '\0';
|
|
|
e5bfac |
/* TODO: save error message and language tag */
|
|
|
e5bfac |
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
|
|
|
e5bfac |
--
|
|
|
e5bfac |
2.17.2
|
|
|
e5bfac |
|