diff options
Diffstat (limited to 'sshbuf.c')
-rw-r--r-- | sshbuf.c | 80 |
1 files changed, 45 insertions, 35 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshbuf.c,v 1.6 2016/01/12 23:42:54 djm Exp $ */ | 1 | /* $OpenBSD: sshbuf.c,v 1.8 2016/11/25 23:22:04 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2011 Damien Miller | 3 | * Copyright (c) 2011 Damien Miller |
4 | * | 4 | * |
@@ -18,7 +18,6 @@ | |||
18 | #define SSHBUF_INTERNAL | 18 | #define SSHBUF_INTERNAL |
19 | #include "includes.h" | 19 | #include "includes.h" |
20 | 20 | ||
21 | #include <sys/param.h> /* roundup */ | ||
22 | #include <sys/types.h> | 21 | #include <sys/types.h> |
23 | #include <signal.h> | 22 | #include <signal.h> |
24 | #include <stdlib.h> | 23 | #include <stdlib.h> |
@@ -27,6 +26,7 @@ | |||
27 | 26 | ||
28 | #include "ssherr.h" | 27 | #include "ssherr.h" |
29 | #include "sshbuf.h" | 28 | #include "sshbuf.h" |
29 | #include "misc.h" | ||
30 | 30 | ||
31 | static inline int | 31 | static inline int |
32 | sshbuf_check_sanity(const struct sshbuf *buf) | 32 | sshbuf_check_sanity(const struct sshbuf *buf) |
@@ -250,7 +250,7 @@ sshbuf_set_max_size(struct sshbuf *buf, size_t max_size) | |||
250 | if (buf->size < SSHBUF_SIZE_INIT) | 250 | if (buf->size < SSHBUF_SIZE_INIT) |
251 | rlen = SSHBUF_SIZE_INIT; | 251 | rlen = SSHBUF_SIZE_INIT; |
252 | else | 252 | else |
253 | rlen = roundup(buf->size, SSHBUF_SIZE_INC); | 253 | rlen = ROUNDUP(buf->size, SSHBUF_SIZE_INC); |
254 | if (rlen > max_size) | 254 | if (rlen > max_size) |
255 | rlen = max_size; | 255 | rlen = max_size; |
256 | explicit_bzero(buf->d + buf->size, buf->alloc - buf->size); | 256 | explicit_bzero(buf->d + buf->size, buf->alloc - buf->size); |
@@ -316,16 +316,13 @@ sshbuf_check_reserve(const struct sshbuf *buf, size_t len) | |||
316 | } | 316 | } |
317 | 317 | ||
318 | int | 318 | int |
319 | sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp) | 319 | sshbuf_allocate(struct sshbuf *buf, size_t len) |
320 | { | 320 | { |
321 | size_t rlen, need; | 321 | size_t rlen, need; |
322 | u_char *dp; | 322 | u_char *dp; |
323 | int r; | 323 | int r; |
324 | 324 | ||
325 | if (dpp != NULL) | 325 | SSHBUF_DBG(("allocate buf = %p len = %zu", buf, len)); |
326 | *dpp = NULL; | ||
327 | |||
328 | SSHBUF_DBG(("reserve buf = %p len = %zu", buf, len)); | ||
329 | if ((r = sshbuf_check_reserve(buf, len)) != 0) | 326 | if ((r = sshbuf_check_reserve(buf, len)) != 0) |
330 | return r; | 327 | return r; |
331 | /* | 328 | /* |
@@ -333,36 +330,49 @@ sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp) | |||
333 | * then pack the buffer, zeroing buf->off. | 330 | * then pack the buffer, zeroing buf->off. |
334 | */ | 331 | */ |
335 | sshbuf_maybe_pack(buf, buf->size + len > buf->max_size); | 332 | sshbuf_maybe_pack(buf, buf->size + len > buf->max_size); |
336 | SSHBUF_TELL("reserve"); | 333 | SSHBUF_TELL("allocate"); |
337 | if (len + buf->size > buf->alloc) { | 334 | if (len + buf->size <= buf->alloc) |
338 | /* | 335 | return 0; /* already have it. */ |
339 | * Prefer to alloc in SSHBUF_SIZE_INC units, but | 336 | |
340 | * allocate less if doing so would overflow max_size. | 337 | /* |
341 | */ | 338 | * Prefer to alloc in SSHBUF_SIZE_INC units, but |
342 | need = len + buf->size - buf->alloc; | 339 | * allocate less if doing so would overflow max_size. |
343 | rlen = roundup(buf->alloc + need, SSHBUF_SIZE_INC); | 340 | */ |
344 | SSHBUF_DBG(("need %zu initial rlen %zu", need, rlen)); | 341 | need = len + buf->size - buf->alloc; |
345 | if (rlen > buf->max_size) | 342 | rlen = ROUNDUP(buf->alloc + need, SSHBUF_SIZE_INC); |
346 | rlen = buf->alloc + need; | 343 | SSHBUF_DBG(("need %zu initial rlen %zu", need, rlen)); |
347 | SSHBUF_DBG(("adjusted rlen %zu", rlen)); | 344 | if (rlen > buf->max_size) |
348 | if ((dp = realloc(buf->d, rlen)) == NULL) { | 345 | rlen = buf->alloc + need; |
349 | SSHBUF_DBG(("realloc fail")); | 346 | SSHBUF_DBG(("adjusted rlen %zu", rlen)); |
350 | if (dpp != NULL) | 347 | if ((dp = realloc(buf->d, rlen)) == NULL) { |
351 | *dpp = NULL; | 348 | SSHBUF_DBG(("realloc fail")); |
352 | return SSH_ERR_ALLOC_FAIL; | 349 | return SSH_ERR_ALLOC_FAIL; |
353 | } | 350 | } |
354 | buf->alloc = rlen; | 351 | buf->alloc = rlen; |
355 | buf->cd = buf->d = dp; | 352 | buf->cd = buf->d = dp; |
356 | if ((r = sshbuf_check_reserve(buf, len)) < 0) { | 353 | if ((r = sshbuf_check_reserve(buf, len)) < 0) { |
357 | /* shouldn't fail */ | 354 | /* shouldn't fail */ |
358 | if (dpp != NULL) | 355 | return r; |
359 | *dpp = NULL; | ||
360 | return r; | ||
361 | } | ||
362 | } | 356 | } |
357 | SSHBUF_TELL("done"); | ||
358 | return 0; | ||
359 | } | ||
360 | |||
361 | int | ||
362 | sshbuf_reserve(struct sshbuf *buf, size_t len, u_char **dpp) | ||
363 | { | ||
364 | u_char *dp; | ||
365 | int r; | ||
366 | |||
367 | if (dpp != NULL) | ||
368 | *dpp = NULL; | ||
369 | |||
370 | SSHBUF_DBG(("reserve buf = %p len = %zu", buf, len)); | ||
371 | if ((r = sshbuf_allocate(buf, len)) != 0) | ||
372 | return r; | ||
373 | |||
363 | dp = buf->d + buf->size; | 374 | dp = buf->d + buf->size; |
364 | buf->size += len; | 375 | buf->size += len; |
365 | SSHBUF_TELL("done"); | ||
366 | if (dpp != NULL) | 376 | if (dpp != NULL) |
367 | *dpp = dp; | 377 | *dpp = dp; |
368 | return 0; | 378 | return 0; |