buffer: Create ssh_buffer_validate_length()

This functions allows if a given length can be obtained from the buffer.

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
(cherry picked from commit c165c396de)
This commit is contained in:
Andreas Schneider
2017-02-23 16:22:04 +01:00
parent 7b8b5eb4ea
commit 5e63b40cde
2 changed files with 28 additions and 3 deletions

View File

@@ -53,6 +53,8 @@ int buffer_add_u32(ssh_buffer buffer, uint32_t data);
int buffer_add_u64(ssh_buffer buffer, uint64_t data); int buffer_add_u64(ssh_buffer buffer, uint64_t data);
int ssh_buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len); int ssh_buffer_add_data(ssh_buffer buffer, const void *data, uint32_t len);
int ssh_buffer_validate_length(struct ssh_buffer_struct *buffer, size_t len);
int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer, int ssh_buffer_pack_va(struct ssh_buffer_struct *buffer,
const char *format, const char *format,
int argc, int argc,

View File

@@ -563,12 +563,15 @@ uint32_t buffer_pass_bytes_end(struct ssh_buffer_struct *buffer, uint32_t len){
* @returns 0 if there is not enough data in buffer, len otherwise. * @returns 0 if there is not enough data in buffer, len otherwise.
*/ */
uint32_t buffer_get_data(struct ssh_buffer_struct *buffer, void *data, uint32_t len){ uint32_t buffer_get_data(struct ssh_buffer_struct *buffer, void *data, uint32_t len){
int rc;
/* /*
* Check for a integer overflow first, then check if not enough data is in * Check for a integer overflow first, then check if not enough data is in
* the buffer. * the buffer.
*/ */
if (buffer->pos + len < len || buffer->pos + len > buffer->used) { rc = ssh_buffer_validate_length(buffer, len);
return 0; if (rc != SSH_OK) {
return 0;
} }
memcpy(data,buffer->data+buffer->pos,len); memcpy(data,buffer->data+buffer->pos,len);
buffer->pos+=len; buffer->pos+=len;
@@ -617,6 +620,24 @@ int buffer_get_u64(struct ssh_buffer_struct *buffer, uint64_t *data){
return buffer_get_data(buffer,data,sizeof(uint64_t)); return buffer_get_data(buffer,data,sizeof(uint64_t));
} }
/**
* @brief Valdiates that the given length can be obtained from the buffer.
*
* @param[in] buffer The buffer to read from.
*
* @param[in] len The length to be checked.
*
* @return SSH_OK if the length is valid, SSH_ERROR otherwise.
*/
int ssh_buffer_validate_length(struct ssh_buffer_struct *buffer, size_t len)
{
if (buffer->pos + len < len || buffer->pos + len > buffer->used) {
return SSH_ERROR;
}
return SSH_OK;
}
/** /**
* @internal * @internal
* *
@@ -630,13 +651,15 @@ struct ssh_string_struct *buffer_get_ssh_string(struct ssh_buffer_struct *buffer
uint32_t stringlen; uint32_t stringlen;
uint32_t hostlen; uint32_t hostlen;
struct ssh_string_struct *str = NULL; struct ssh_string_struct *str = NULL;
int rc;
if (buffer_get_u32(buffer, &stringlen) == 0) { if (buffer_get_u32(buffer, &stringlen) == 0) {
return NULL; return NULL;
} }
hostlen = ntohl(stringlen); hostlen = ntohl(stringlen);
/* verify if there is enough space in buffer to get it */ /* verify if there is enough space in buffer to get it */
if (buffer->pos + hostlen < hostlen || buffer->pos + hostlen > buffer->used) { rc = ssh_buffer_validate_length(buffer, hostlen);
if (rc != SSH_OK) {
return NULL; /* it is indeed */ return NULL; /* it is indeed */
} }
str = ssh_string_new(hostlen); str = ssh_string_new(hostlen);