1 |
commit a699c44ea18d83fe99314155ed35a87092ce68c9 |
2 |
Author: Michael Buckley <michael@panic.com> |
3 |
Date: Wed Dec 5 12:01:34 2018 -0800 |
4 |
|
5 |
Additional length checks to prevent out-of-bounds reads and writes in _libssh2_packet_add(). |
6 |
|
7 |
diff --git a/src/packet.c b/src/packet.c |
8 |
index 5f1feb8..1d50444 100644 |
9 |
--- a/src/packet.c |
10 |
+++ b/src/packet.c |
11 |
@@ -775,8 +775,8 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, |
12 |
uint32_t len = _libssh2_ntohu32(data + 5); |
13 |
unsigned char want_reply = 1; |
14 |
|
15 |
- if(len < (datalen - 10)) |
16 |
- want_reply = data[9 + len]; |
17 |
+ if((len + 9) < datalen) |
18 |
+ want_reply = data[len + 9]; |
19 |
|
20 |
_libssh2_debug(session, |
21 |
LIBSSH2_TRACE_CONN, |
22 |
@@ -784,6 +784,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, |
23 |
channel, len, data + 9, want_reply); |
24 |
|
25 |
if (len == sizeof("exit-status") - 1 |
26 |
+ && (sizeof("exit-status") - 1 + 9) <= datalen |
27 |
&& !memcmp("exit-status", data + 9, |
28 |
sizeof("exit-status") - 1)) { |
29 |
|
30 |
@@ -792,7 +793,7 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, |
31 |
channelp = |
32 |
_libssh2_channel_locate(session, channel); |
33 |
|
34 |
- if (channelp) { |
35 |
+ if (channelp && (sizeof("exit-status") + 13) <= datalen) { |
36 |
channelp->exit_status = |
37 |
_libssh2_ntohu32(data + 9 + sizeof("exit-status")); |
38 |
_libssh2_debug(session, LIBSSH2_TRACE_CONN, |
39 |
@@ -805,13 +806,14 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, |
40 |
|
41 |
} |
42 |
else if (len == sizeof("exit-signal") - 1 |
43 |
+ && (sizeof("exit-signal") - 1 + 9) <= datalen |
44 |
&& !memcmp("exit-signal", data + 9, |
45 |
sizeof("exit-signal") - 1)) { |
46 |
/* command terminated due to signal */ |
47 |
if(datalen >= 20) |
48 |
channelp = _libssh2_channel_locate(session, channel); |
49 |
|
50 |
- if (channelp) { |
51 |
+ if (channelp && (sizeof("exit-signal") + 13) <= datalen) { |
52 |
/* set signal name (without SIG prefix) */ |
53 |
uint32_t namelen = |
54 |
_libssh2_ntohu32(data + 9 + sizeof("exit-signal")); |
55 |
@@ -820,9 +822,9 @@ _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data, |
56 |
if (!channelp->exit_signal) |
57 |
rc = _libssh2_error(session, LIBSSH2_ERROR_ALLOC, |
58 |
"memory for signal name"); |
59 |
- else { |
60 |
+ else if ((sizeof("exit-signal") + 13 + namelen <= datalen)) { |
61 |
memcpy(channelp->exit_signal, |
62 |
- data + 13 + sizeof("exit_signal"), namelen); |
63 |
+ data + 13 + sizeof("exit-signal"), namelen); |
64 |
channelp->exit_signal[namelen] = '\0'; |
65 |
/* TODO: save error message and language tag */ |
66 |
_libssh2_debug(session, LIBSSH2_TRACE_CONN, |