1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-11-29 01:03:57 +03:00

buffer: Always preallocate a buffer with 64 bytes

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Andreas Schneider
2018-08-31 17:02:08 +02:00
parent c1c32bda14
commit d2131b286f

View File

@@ -46,10 +46,10 @@
*/ */
struct ssh_buffer_struct { struct ssh_buffer_struct {
bool secure; bool secure;
char *data; size_t used;
uint32_t used; size_t allocated;
uint32_t allocated; size_t pos;
uint32_t pos; uint8_t *data;
}; };
/** /**
@@ -80,21 +80,21 @@ static void buffer_verify(ssh_buffer buf)
if (buf->used > buf->allocated) { if (buf->used > buf->allocated) {
fprintf(stderr, fprintf(stderr,
"BUFFER ERROR: allocated %u, used %u\n", "BUFFER ERROR: allocated %zu, used %zu\n",
buf->allocated, buf->allocated,
buf->used); buf->used);
do_abort = true; do_abort = true;
} }
if (buf->pos > buf->used) { if (buf->pos > buf->used) {
fprintf(stderr, fprintf(stderr,
"BUFFER ERROR: position %u, used %u\n", "BUFFER ERROR: position %zu, used %zu\n",
buf->pos, buf->pos,
buf->used); buf->used);
do_abort = true; do_abort = true;
} }
if (buf->pos > buf->allocated) { if (buf->pos > buf->allocated) {
fprintf(stderr, fprintf(stderr,
"BUFFER ERROR: position %u, allocated %u\n", "BUFFER ERROR: position %zu, allocated %zu\n",
buf->pos, buf->pos,
buf->allocated); buf->allocated);
do_abort = true; do_abort = true;
@@ -113,14 +113,28 @@ static void buffer_verify(ssh_buffer buf)
* *
* @return A newly initialized SSH buffer, NULL on error. * @return A newly initialized SSH buffer, NULL on error.
*/ */
struct ssh_buffer_struct *ssh_buffer_new(void) { struct ssh_buffer_struct *ssh_buffer_new(void)
struct ssh_buffer_struct *buf = {
calloc(1, sizeof(struct ssh_buffer_struct)); struct ssh_buffer_struct *buf = NULL;
int rc;
buf = calloc(1, sizeof(struct ssh_buffer_struct));
if (buf == NULL) { if (buf == NULL) {
return NULL; return NULL;
} }
/*
* Always preallocate 64 bytes.
*
* -1 for ralloc_buffer magic.
*/
rc = ssh_buffer_allocate_size(buf, 64 - 1);
if (rc != 0) {
SAFE_FREE(buf);
return NULL;
}
buffer_verify(buf); buffer_verify(buf);
return buf; return buf;
} }
@@ -161,9 +175,10 @@ void ssh_buffer_set_secure(ssh_buffer buffer)
buffer->secure = true; buffer->secure = true;
} }
static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) { static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed)
{
size_t smallest = 1; size_t smallest = 1;
char *new; uint8_t *new = NULL;
buffer_verify(buffer); buffer_verify(buffer);
@@ -175,25 +190,24 @@ static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) {
smallest <<= 1; smallest <<= 1;
} }
needed = smallest; needed = smallest;
if (buffer->secure) { if (buffer->secure) {
new = malloc(needed); new = malloc(needed);
if (new == NULL) { if (new == NULL) {
return -1; return -1;
} }
if (buffer->used > 0) {
memcpy(new, buffer->data, buffer->used); memcpy(new, buffer->data, buffer->used);
explicit_bzero(buffer->data, buffer->used); explicit_bzero(buffer->data, buffer->used);
SAFE_FREE(buffer->data); SAFE_FREE(buffer->data);
}
} else { } else {
new = realloc(buffer->data, needed); new = realloc(buffer->data, needed);
if (new == NULL) { if (new == NULL) {
buffer->data = NULL;
return -1; return -1;
} }
} }
buffer->data = new; buffer->data = new;
buffer->allocated = needed; buffer->allocated = needed;
buffer_verify(buffer); buffer_verify(buffer);
return 0; return 0;
} }
@@ -204,7 +218,7 @@ static int realloc_buffer(struct ssh_buffer_struct *buffer, size_t needed) {
*/ */
static void buffer_shift(ssh_buffer buffer) static void buffer_shift(ssh_buffer buffer)
{ {
uint32_t burn_pos = buffer->pos; size_t burn_pos = buffer->pos;
buffer_verify(buffer); buffer_verify(buffer);
@@ -234,9 +248,14 @@ static void buffer_shift(ssh_buffer buffer)
*/ */
int ssh_buffer_reinit(struct ssh_buffer_struct *buffer) int ssh_buffer_reinit(struct ssh_buffer_struct *buffer)
{ {
if (buffer == NULL) {
return -1;
}
buffer_verify(buffer); buffer_verify(buffer);
if (buffer->used > 0) {
explicit_bzero(buffer->data, buffer->used); if (buffer->secure && buffer->allocated > 0) {
explicit_bzero(buffer->data, buffer->allocated);
} }
buffer->used = 0; buffer->used = 0;
buffer->pos = 0; buffer->pos = 0;
@@ -246,6 +265,7 @@ int ssh_buffer_reinit(struct ssh_buffer_struct *buffer)
return -1; return -1;
} }
} }
buffer_verify(buffer); buffer_verify(buffer);
return 0; return 0;