From: Simon Glass Date: Mon, 28 Feb 2022 19:08:22 +0000 (-0700) Subject: abuf: Correct a corner case with abuf_realloc() X-Git-Url: http://git.dujemihanovic.xyz/img/sics.gif?a=commitdiff_plain;h=99aca9efe10c005189b47160d178d18f14301c7e;p=u-boot.git 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 --- diff --git a/lib/abuf.c b/lib/abuf.c index 4b17e0b8c0..1635d58682 100644 --- a/lib/abuf.c +++ b/lib/abuf.c @@ -51,9 +51,11 @@ bool abuf_realloc(struct abuf *abuf, size_t new_size) /* not currently allocated and new size is larger. Alloc and * copy in data. The new space is not inited. */ - ptr = memdup(abuf->data, new_size); + ptr = malloc(new_size); if (!ptr) return false; + if (abuf->size) + memcpy(ptr, abuf->data, abuf->size); abuf->data = ptr; abuf->size = new_size; abuf->alloced = true; diff --git a/test/lib/abuf.c b/test/lib/abuf.c index 086c9b2282..42ee4c1755 100644 --- a/test/lib/abuf.c +++ b/test/lib/abuf.c @@ -126,6 +126,35 @@ static int lib_test_abuf_realloc(struct unit_test_state *uts) } 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 */ static int lib_test_abuf_large(struct unit_test_state *uts) {