abuf: Correct a corner case with abuf_realloc()

If the buffer is empty and not allocated, then abuf_realloc() tries to
copy invalid data. This happens because an incorrect change to use
memdup() was added after the original code was written.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass 2022-02-28 12:08:22 -07:00 committed by Tom Rini
parent 64aefc4800
commit 99aca9efe1
2 changed files with 32 additions and 1 deletions

View File

@ -51,9 +51,11 @@ bool abuf_realloc(struct abuf *abuf, size_t new_size)
/* not currently allocated and new size is larger. Alloc and /* not currently allocated and new size is larger. Alloc and
* copy in data. The new space is not inited. * copy in data. The new space is not inited.
*/ */
ptr = memdup(abuf->data, new_size); ptr = malloc(new_size);
if (!ptr) if (!ptr)
return false; return false;
if (abuf->size)
memcpy(ptr, abuf->data, abuf->size);
abuf->data = ptr; abuf->data = ptr;
abuf->size = new_size; abuf->size = new_size;
abuf->alloced = true; abuf->alloced = true;

View File

@ -126,6 +126,35 @@ static int lib_test_abuf_realloc(struct unit_test_state *uts)
} }
LIB_TEST(lib_test_abuf_realloc, 0); LIB_TEST(lib_test_abuf_realloc, 0);
/* Test abuf_realloc() on an non-allocated buffer of zero size */
static int lib_test_abuf_realloc_size(struct unit_test_state *uts)
{
struct abuf buf;
ulong start;
start = ut_check_free();
abuf_init(&buf);
/* Allocate some space */
ut_asserteq(true, abuf_realloc(&buf, TEST_DATA_LEN));
ut_assertnonnull(buf.data);
ut_asserteq(TEST_DATA_LEN, buf.size);
ut_asserteq(true, buf.alloced);
/* Free it */
ut_asserteq(true, abuf_realloc(&buf, 0));
ut_assertnull(buf.data);
ut_asserteq(0, buf.size);
ut_asserteq(false, buf.alloced);
/* Check for memory leaks */
ut_assertok(ut_check_delta(start));
return 0;
}
LIB_TEST(lib_test_abuf_realloc_size, 0);
/* Test handling of buffers that are too large */ /* Test handling of buffers that are too large */
static int lib_test_abuf_large(struct unit_test_state *uts) static int lib_test_abuf_large(struct unit_test_state *uts)
{ {