aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2017-02-23 16:24:17 +0100
committerAndreas Schneider <asn@cryptomilk.org>2017-04-13 16:28:18 +0200
commita7cce775503960da6a27d1c6af740f617d7f5ad5 (patch)
treed88b546f00eb81aced49d7b01dea26fdb217c7ae
parent5e63b40cde9b298b0a55a405551dd1d858e9ab18 (diff)
downloadlibssh-a7cce775503960da6a27d1c6af740f617d7f5ad5.tar.gz
libssh-a7cce775503960da6a27d1c6af740f617d7f5ad5.tar.xz
libssh-a7cce775503960da6a27d1c6af740f617d7f5ad5.zip
buffer: Validate the length before before memory allocation
Check if the size the other party sent is a valid size in the transmitted buffer. Thanks to Alex Gaynor for finding and reporting the issue. Signed-off-by: Andreas Schneider <asn@cryptomilk.org> (cherry picked from commit 68b7ca6e925f5744f5c52c56094041d63789efaa)
-rw-r--r--src/buffer.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/buffer.c b/src/buffer.c
index 1b7e09ea..566701ca 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -890,11 +890,13 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
char **cstring;
void **data;
} o;
- size_t len, rlen;
+ size_t len, rlen, max_len;
uint32_t u32len;
va_list ap_copy;
int count;
+ max_len = ssh_buffer_get_len(buffer);
+
/* copy the argument list in case a rollback is needed */
va_copy(ap_copy, ap);
@@ -944,10 +946,16 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
break;
}
len = ntohl(u32len);
- if (len > UINT_MAX - 1){
+ if (len > max_len - 1) {
rc = SSH_ERROR;
break;
}
+
+ rc = ssh_buffer_validate_length(buffer, len);
+ if (rc != SSH_OK) {
+ break;
+ }
+
*o.cstring = malloc(len + 1);
if (*o.cstring == NULL){
rc = SSH_ERROR;
@@ -965,6 +973,15 @@ int ssh_buffer_unpack_va(struct ssh_buffer_struct *buffer,
break;
case 'P':
len = va_arg(ap, size_t);
+ if (len > max_len - 1) {
+ rc = SSH_ERROR;
+ break;
+ }
+
+ rc = ssh_buffer_validate_length(buffer, len);
+ if (rc != SSH_OK) {
+ break;
+ }
o.data = va_arg(ap, void **);
count++;