Skip to content

Commit

Permalink
split allocation out of sshbuf_reserve() into a separate
Browse files Browse the repository at this point in the history
sshbuf_allocate() function; ok markus@
  • Loading branch information
djmdjm committed Nov 25, 2016
1 parent b19fdf1 commit 66d9cec
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 34 deletions.
76 changes: 43 additions & 33 deletions usr.bin/ssh/sshbuf.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: sshbuf.c,v 1.7 2016/09/12 01:22:38 deraadt Exp $ */
/* $OpenBSD: sshbuf.c,v 1.8 2016/11/25 23:22:04 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
Expand Down Expand Up @@ -314,53 +314,63 @@ sshbuf_check_reserve(const struct sshbuf *buf, size_t len)
}

int
sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp)
sshbuf_allocate(struct sshbuf *buf, size_t len)
{
size_t rlen, need;
u_char *dp;
int r;

if (dpp != NULL)
*dpp = NULL;

SSHBUF_DBG(("reserve buf = %p len = %zu", buf, len));
SSHBUF_DBG(("allocate buf = %p len = %zu", buf, len));
if ((r = sshbuf_check_reserve(buf, len)) != 0)
return r;
/*
* If the requested allocation appended would push us past max_size
* then pack the buffer, zeroing buf->off.
*/
sshbuf_maybe_pack(buf, buf->size + len > buf->max_size);
SSHBUF_TELL("reserve");
if (len + buf->size > buf->alloc) {
/*
* Prefer to alloc in SSHBUF_SIZE_INC units, but
* allocate less if doing so would overflow max_size.
*/
need = len + buf->size - buf->alloc;
rlen = ROUNDUP(buf->alloc + need, SSHBUF_SIZE_INC);
SSHBUF_DBG(("need %zu initial rlen %zu", need, rlen));
if (rlen > buf->max_size)
rlen = buf->alloc + need;
SSHBUF_DBG(("adjusted rlen %zu", rlen));
if ((dp = realloc(buf->d, rlen)) == NULL) {
SSHBUF_DBG(("realloc fail"));
if (dpp != NULL)
*dpp = NULL;
return SSH_ERR_ALLOC_FAIL;
}
buf->alloc = rlen;
buf->cd = buf->d = dp;
if ((r = sshbuf_check_reserve(buf, len)) < 0) {
/* shouldn't fail */
if (dpp != NULL)
*dpp = NULL;
return r;
}
SSHBUF_TELL("allocate");
if (len + buf->size <= buf->alloc)
return 0; /* already have it. */

/*
* Prefer to alloc in SSHBUF_SIZE_INC units, but
* allocate less if doing so would overflow max_size.
*/
need = len + buf->size - buf->alloc;
rlen = ROUNDUP(buf->alloc + need, SSHBUF_SIZE_INC);
SSHBUF_DBG(("need %zu initial rlen %zu", need, rlen));
if (rlen > buf->max_size)
rlen = buf->alloc + need;
SSHBUF_DBG(("adjusted rlen %zu", rlen));
if ((dp = realloc(buf->d, rlen)) == NULL) {
SSHBUF_DBG(("realloc fail"));
return SSH_ERR_ALLOC_FAIL;
}
buf->alloc = rlen;
buf->cd = buf->d = dp;
if ((r = sshbuf_check_reserve(buf, len)) < 0) {
/* shouldn't fail */
return r;
}
SSHBUF_TELL("done");
return 0;
}

int
sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp)
{
u_char *dp;
int r;

if (dpp != NULL)
*dpp = NULL;

SSHBUF_DBG(("reserve buf = %p len = %zu", buf, len));
if ((r = sshbuf_allocate(buf, len)) != 0)
return r;

dp = buf->d + buf->size;
buf->size += len;
SSHBUF_TELL("done");
if (dpp != NULL)
*dpp = dp;
return 0;
Expand Down
10 changes: 9 additions & 1 deletion usr.bin/ssh/sshbuf.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $OpenBSD: sshbuf.h,v 1.7 2016/05/02 08:49:03 djm Exp $ */
/* $OpenBSD: sshbuf.h,v 1.8 2016/11/25 23:22:04 djm Exp $ */
/*
* Copyright (c) 2011 Damien Miller
*
Expand Down Expand Up @@ -134,6 +134,14 @@ u_char *sshbuf_mutable_ptr(const struct sshbuf *buf);
*/
int sshbuf_check_reserve(const struct sshbuf *buf, size_t len);

/*
* Preallocates len additional bytes in buf.
* Useful for cases where the caller knows how many bytes will ultimately be
* required to avoid realloc in the buffer code.
* Returns 0 on success, or a negative SSH_ERR_* error code on failure.
*/
int sshbuf_allocate(struct sshbuf *buf, size_t len);

/*
* Reserve len bytes in buf.
* Returns 0 on success and a pointer to the first reserved byte via the
Expand Down

0 comments on commit 66d9cec

Please sign in to comment.