diff options
author | Andreas Schneider <asn@cryptomilk.org> | 2017-02-23 16:24:17 +0100 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2017-04-13 16:28:18 +0200 |
commit | a7cce775503960da6a27d1c6af740f617d7f5ad5 (patch) | |
tree | d88b546f00eb81aced49d7b01dea26fdb217c7ae | |
parent | 5e63b40cde9b298b0a55a405551dd1d858e9ab18 (diff) | |
download | libssh-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.c | 21 |
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++; |