libssh2/0001-packet.c-improved-packet-parsing-in-packet_queue_lis.patch

98 lines
3.8 KiB
Diff

From 80d3ea5b413d269ec77aebbb0aabbe738ba31796 Mon Sep 17 00:00:00 2001
From: Will Cosgrove <will@panic.com>
Date: Wed, 4 Sep 2019 12:16:52 -0700
Subject: [PATCH] packet.c: improved packet parsing in packet_queue_listener
(#404)
* improved bounds checking in packet_queue_listener
file: packet.c
notes:
improved parsing packet in packet_queue_listener
---
src/packet.c | 63 +++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 43 insertions(+), 20 deletions(-)
diff --git a/src/packet.c b/src/packet.c
index 2e01bfc..c83a68d 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -85,30 +85,53 @@ packet_queue_listener(LIBSSH2_SESSION * session, unsigned char *data,
char failure_code = SSH_OPEN_ADMINISTRATIVELY_PROHIBITED;
int rc;
- (void) datalen;
-
if(listen_state->state == libssh2_NB_state_idle) {
- unsigned char *s = data + (sizeof("forwarded-tcpip") - 1) + 5;
- listen_state->sender_channel = _libssh2_ntohu32(s);
- s += 4;
+ unsigned long offset = (sizeof("forwarded-tcpip") - 1) + 5;
+ size_t temp_len = 0;
+ struct string_buf buf;
+ buf.data = data;
+ buf.dataptr = buf.data;
+ buf.len = datalen;
+
+ if(datalen < offset) {
+ return _libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
+ "Unexpected packet size");
+ }
- listen_state->initial_window_size = _libssh2_ntohu32(s);
- s += 4;
- listen_state->packet_size = _libssh2_ntohu32(s);
- s += 4;
+ buf.dataptr += offset;
- listen_state->host_len = _libssh2_ntohu32(s);
- s += 4;
- listen_state->host = s;
- s += listen_state->host_len;
- listen_state->port = _libssh2_ntohu32(s);
- s += 4;
+ if(_libssh2_get_u32(&buf, &(listen_state->sender_channel))) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Data too short extracting channel");
+ }
+ if(_libssh2_get_u32(&buf, &(listen_state->initial_window_size))) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Data too short extracting window size");
+ }
+ if(_libssh2_get_u32(&buf, &(listen_state->packet_size))) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Data too short extracting packet");
+ }
+ if(_libssh2_get_string(&buf, &(listen_state->host), &temp_len)) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Data too short extracting host");
+ }
+ listen_state->host_len = (uint32_t)temp_len;
- listen_state->shost_len = _libssh2_ntohu32(s);
- s += 4;
- listen_state->shost = s;
- s += listen_state->shost_len;
- listen_state->sport = _libssh2_ntohu32(s);
+ if(_libssh2_get_u32(&buf, &(listen_state->port))) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Data too short extracting port");
+ }
+ if(_libssh2_get_string(&buf, &(listen_state->shost), &temp_len)) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Data too short extracting shost");
+ }
+ listen_state->shost_len = (uint32_t)temp_len;
+
+ if(_libssh2_get_u32(&buf, &(listen_state->sport))) {
+ return _libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
+ "Data too short extracting sport");
+ }
_libssh2_debug(session, LIBSSH2_TRACE_CONN,
"Remote received connection from %s:%ld to %s:%ld",
--
1.8.3.1