From patchwork Wed Dec 25 18:38:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ren=C3=A9_Scharfe?= X-Patchwork-Id: 13920848 Received: from mout.web.de (mout.web.de [212.227.17.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BF3E020DF4 for ; Wed, 25 Dec 2024 18:38:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=212.227.17.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735151923; cv=none; b=m5TbfM4cKjpyZuNDxBae9fpaDR0tYpg6/ihTHCrSsem6XZ3eeQHRb3z+JMgMYm6XkCBMueSkj1y7KeNI1QCcj90k7kfoFqIXFKkViUqy3Ln24UZ+qt/+oi72BpPMVNymoO9ytwIdwgvfbCTPXcImhz9Zppoz2VznY4YA1GO2kb4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735151923; c=relaxed/simple; bh=POxh7E39/LDi1Tp+15CooUllriNWR/Mbl/mkcGGu+14=; h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: In-Reply-To:Content-Type; b=mhTKntdzdcxTpgGvP8zzbEeu1GKk2yPP99kM8ehtmCnFhhzCvAYUa0WdCqQ0MyxUH+MPGIzImyHDrpMHZN/hZpJdfCSeguKqa9lAmqs9Zj2N9gGBcS7jHfhZ7EuNILb86bdv09BHPT2qjskrOX3EJ0IE4mtpwG5lfCyIYJatuUE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de; spf=pass smtp.mailfrom=web.de; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b=SaKPdCFN; arc=none smtp.client-ip=212.227.17.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=web.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b="SaKPdCFN" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=web.de; s=s29768273; t=1735151910; x=1735756710; i=l.s.r@web.de; bh=ryuBBxTbqkiOMgkYoj+AfwZwHHZ0ZoGzfZyy0KsurDY=; h=X-UI-Sender-Class:Message-ID:Date:MIME-Version:Subject:From:To: Cc:References:In-Reply-To:Content-Type:Content-Transfer-Encoding: cc:content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=SaKPdCFNQcEpS1yIB87yE7kNXRcoENJfTewm3o8n2pL985HcAwDxGzZE6kD2w02t v/ZUz3COxVAyZYziLTfIXWlCXe1FDQA7AO2XhYDzE/83xcowDthXJDORD4VOuwzfL 2CEFG6FxNCfuPGUtQjw1th+nOFf9FNG/kw3gt+whbnMB+zMVOXisaR1ItlWkdQ7t7 4JBGahZD9UWj/ufjyMWl5G7LPA1DUaNrzG1CcwV80snEAdmyh5u2x3QUOT7W19ukz NWyU+gN3GJZg4vewVSL6fpnDP0emEL1xDN8l28gC92gZrQQZ4syuf4gGaI8XGE8cM YLzjJye2bnlBUPKO1g== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [192.168.178.29] ([79.203.20.45]) by smtp.web.de (mrweb106 [213.165.67.124]) with ESMTPSA (Nemesis) id 1MtyA2-1tetvm1nfY-00xDtm; Wed, 25 Dec 2024 19:38:30 +0100 Message-ID: <9b2f4baa-b602-4cc5-8dfc-dd941b1d7af6@web.de> Date: Wed, 25 Dec 2024 19:38:29 +0100 Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 1/4] reftable: avoid leaks on realloc error From: =?utf-8?q?Ren=C3=A9_Scharfe?= To: Git List Cc: Patrick Steinhardt References: <2b9fba8d-be63-4145-9d25-a2151e422cfa@web.de> Content-Language: en-US In-Reply-To: <2b9fba8d-be63-4145-9d25-a2151e422cfa@web.de> X-Provags-ID: V03:K1:BC8gZ3xBUQAb3cdWLBF/IWhfTEy8wPIs+5Hn6YedHjtG6Txrz6S JyfY4Jd0eexOxWuPmkCa9/6maPXhybhJVUnwXcYbV4zh40Bzqlpgn0i/LE3sQVmT5HJ1GoX oq35Ow9KKEErxqrUwlhEI9RPLu/9w4rGGXAtn2BJgYrN/XgYEJ3J0WW1iwwxR5QgmTd3/FP kkTyYZ/Ty1e2gbZPD0EdQ== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:SD43NyU05CY=;yCtXbLYgVGSdIDjAXeRsMpwiyw9 xmfac0yjJCf0Vvss9ClW4xM/g4edf6boXP3JJ3XlirOgP5hSzR37E+E3hYxJoPWbmPqDAwPeX ywHRZUtiPRAil0Gmq3W6KJ6zsrisUiXR0wA3SerxtMfGibDcU2cEkHAon75SXl8qwziRAFW7u 4rjazh9hfIKYn5VX/bNO+C4RTffoWKuxZK/8HUKfNZoR+cNd0ZrBCP1enid6WQza6502IHs3x E2g6SZpcyXR9wMbfea7t/LNBrZApDOMkXyrcs2guW/o0P+D9q/fhRNDoAKu4wdBvQQ8QDBU9y TQtBN89NvywrGfTXx74aqKLp3bNMLcPYbLK7nt08LKKcbwyhhx1KxBryNf0HTgMqb3w0Bed48 gJ0A3EUDAs1qMx3ybg3vi3aGq0oEi5ViAMb4+pxuGdP34NTK7z+Ib809l4zIRvYI9H3Or2d2M okzfYKbcPw7T7BthSZ/njbdfueNn7awG7zNe8lw6/UzzyzYNDAiLcmFUX3QrnkF30OtCF0QHg 4DF93YPjCQNjZrru07ve/v0UWxyXAVvbMw/0HylBFVwAlxn9R+1bCJieRv3lgCReuAFS8mUIZ 9If7dDCHg1Zb7a+/r9O3gIQxqBZPurNtL377EL6yLbw/4TK3RzjMIsR57d9lawS82BZ8GLUSK 03mSzEUKU9KEjUVz5oTiKFrExa8AyvHoaE6/fbok+15mjOHXYPd1mfw3OYqp9a3gQ9gufYyjR ElulnORxQ6B+ZlC5kpRAEFiMSzIjiHpi3h0becM1424jUXJIs77FNPDSx8yGGd82T1n6yqVHt y8rCX0Rbs6vK9fQSRveSibtMhVVGOVsmHvkZ7+waceFUu4/5ADY4fZqLVWPUrLQJqKxbtuqDm nw6IQkSTtEwyXwTfjuSJZ3uP6jcunedOd1gErBNdxsuVw+8joo9VUdLJvRAS7WWxV+qnC4PZE 6xApXOTySYQ8wPyJ4cxc4LGHJmmh+iqGEbet6QirU0nVs6C12RyfieoOsT71HFDgk5z2gyasI y21ZmXYWJm9CugBGMpBTgrLS9fsZ9jpeD6OkDBzYBdeKTKGTa/2qVjDhPkfSE8KkmUui8nzSi J6XBz79PY= When realloc(3) fails, it returns NULL and keeps the original allocation intact. REFTABLE_ALLOC_GROW overwrites both the original pointer and the allocation count variable in that case, simultaneously leaking the original allocation and misrepresenting the number of storable items. parse_names() and reftable_buf_add() avoid leaking by restoring the original pointer value on failure, but all other callers seem to be OK with losing the old allocation. Add a new variant of the macro, REFTABLE_ALLOC_GROW_OR_NULL, which plugs the leak and zeros the allocation counter. Use it for those callers. Signed-off-by: René Scharfe --- reftable/basics.h | 10 ++++++++++ reftable/block.c | 10 ++++++---- reftable/pq.c | 2 +- reftable/record.c | 12 ++++++------ reftable/stack.c | 8 +++++--- reftable/writer.c | 5 +++-- 6 files changed, 31 insertions(+), 16 deletions(-) -- 2.47.1 diff --git a/reftable/basics.h b/reftable/basics.h index 36beda2c25..259f4c274c 100644 --- a/reftable/basics.h +++ b/reftable/basics.h @@ -129,6 +129,16 @@ char *reftable_strdup(const char *str); REFTABLE_REALLOC_ARRAY(x, alloc); \ } \ } while (0) + +#define REFTABLE_ALLOC_GROW_OR_NULL(x, nr, alloc) do { \ + void *reftable_alloc_grow_or_null_orig_ptr = (x); \ + REFTABLE_ALLOC_GROW((x), (nr), (alloc)); \ + if (!(x)) { \ + reftable_free(reftable_alloc_grow_or_null_orig_ptr); \ + alloc = 0; \ + } \ +} while (0) + #define REFTABLE_FREE_AND_NULL(p) do { reftable_free(p); (p) = NULL; } while (0) #ifndef REFTABLE_ALLOW_BANNED_ALLOCATORS diff --git a/reftable/block.c b/reftable/block.c index 0198078485..9858bbc7c5 100644 --- a/reftable/block.c +++ b/reftable/block.c @@ -53,7 +53,8 @@ static int block_writer_register_restart(struct block_writer *w, int n, if (2 + 3 * rlen + n > w->block_size - w->next) return -1; if (is_restart) { - REFTABLE_ALLOC_GROW(w->restarts, w->restart_len + 1, w->restart_cap); + REFTABLE_ALLOC_GROW_OR_NULL(w->restarts, w->restart_len + 1, + w->restart_cap); if (!w->restarts) return REFTABLE_OUT_OF_MEMORY_ERROR; w->restarts[w->restart_len++] = w->next; @@ -176,7 +177,8 @@ int block_writer_finish(struct block_writer *w) * is guaranteed to return `Z_STREAM_END`. */ compressed_len = deflateBound(w->zstream, src_len); - REFTABLE_ALLOC_GROW(w->compressed, compressed_len, w->compressed_cap); + REFTABLE_ALLOC_GROW_OR_NULL(w->compressed, compressed_len, + w->compressed_cap); if (!w->compressed) { ret = REFTABLE_OUT_OF_MEMORY_ERROR; return ret; @@ -235,8 +237,8 @@ int block_reader_init(struct block_reader *br, struct reftable_block *block, uLong src_len = block->len - block_header_skip; /* Log blocks specify the *uncompressed* size in their header. */ - REFTABLE_ALLOC_GROW(br->uncompressed_data, sz, - br->uncompressed_cap); + REFTABLE_ALLOC_GROW_OR_NULL(br->uncompressed_data, sz, + br->uncompressed_cap); if (!br->uncompressed_data) { err = REFTABLE_OUT_OF_MEMORY_ERROR; goto done; diff --git a/reftable/pq.c b/reftable/pq.c index 6ee1164dd3..5591e875e1 100644 --- a/reftable/pq.c +++ b/reftable/pq.c @@ -49,7 +49,7 @@ int merged_iter_pqueue_add(struct merged_iter_pqueue *pq, const struct pq_entry { size_t i = 0; - REFTABLE_ALLOC_GROW(pq->heap, pq->len + 1, pq->cap); + REFTABLE_ALLOC_GROW_OR_NULL(pq->heap, pq->len + 1, pq->cap); if (!pq->heap) return REFTABLE_OUT_OF_MEMORY_ERROR; pq->heap[pq->len++] = *e; diff --git a/reftable/record.c b/reftable/record.c index fb5652ed57..04429d23fe 100644 --- a/reftable/record.c +++ b/reftable/record.c @@ -246,8 +246,8 @@ static int reftable_ref_record_copy_from(void *rec, const void *src_rec, if (src->refname) { size_t refname_len = strlen(src->refname); - REFTABLE_ALLOC_GROW(ref->refname, refname_len + 1, - ref->refname_cap); + REFTABLE_ALLOC_GROW_OR_NULL(ref->refname, refname_len + 1, + ref->refname_cap); if (!ref->refname) { err = REFTABLE_OUT_OF_MEMORY_ERROR; goto out; @@ -385,7 +385,7 @@ static int reftable_ref_record_decode(void *rec, struct reftable_buf key, SWAP(r->refname, refname); SWAP(r->refname_cap, refname_cap); - REFTABLE_ALLOC_GROW(r->refname, key.len + 1, r->refname_cap); + REFTABLE_ALLOC_GROW_OR_NULL(r->refname, key.len + 1, r->refname_cap); if (!r->refname) { err = REFTABLE_OUT_OF_MEMORY_ERROR; goto done; @@ -839,7 +839,7 @@ static int reftable_log_record_decode(void *rec, struct reftable_buf key, if (key.len <= 9 || key.buf[key.len - 9] != 0) return REFTABLE_FORMAT_ERROR; - REFTABLE_ALLOC_GROW(r->refname, key.len - 8, r->refname_cap); + REFTABLE_ALLOC_GROW_OR_NULL(r->refname, key.len - 8, r->refname_cap); if (!r->refname) { err = REFTABLE_OUT_OF_MEMORY_ERROR; goto done; @@ -947,8 +947,8 @@ static int reftable_log_record_decode(void *rec, struct reftable_buf key, } string_view_consume(&in, n); - REFTABLE_ALLOC_GROW(r->value.update.message, scratch->len + 1, - r->value.update.message_cap); + REFTABLE_ALLOC_GROW_OR_NULL(r->value.update.message, scratch->len + 1, + r->value.update.message_cap); if (!r->value.update.message) { err = REFTABLE_OUT_OF_MEMORY_ERROR; goto done; diff --git a/reftable/stack.c b/reftable/stack.c index 634f0c5425..531660a49f 100644 --- a/reftable/stack.c +++ b/reftable/stack.c @@ -317,7 +317,9 @@ static int reftable_stack_reload_once(struct reftable_stack *st, * thus need to keep them alive here, which we * do by bumping their refcount. */ - REFTABLE_ALLOC_GROW(reused, reused_len + 1, reused_alloc); + REFTABLE_ALLOC_GROW_OR_NULL(reused, + reused_len + 1, + reused_alloc); if (!reused) { err = REFTABLE_OUT_OF_MEMORY_ERROR; goto done; @@ -949,8 +951,8 @@ int reftable_addition_add(struct reftable_addition *add, if (err < 0) goto done; - REFTABLE_ALLOC_GROW(add->new_tables, add->new_tables_len + 1, - add->new_tables_cap); + REFTABLE_ALLOC_GROW_OR_NULL(add->new_tables, add->new_tables_len + 1, + add->new_tables_cap); if (!add->new_tables) { err = REFTABLE_OUT_OF_MEMORY_ERROR; goto done; diff --git a/reftable/writer.c b/reftable/writer.c index 624e90fb53..740c98038e 100644 --- a/reftable/writer.c +++ b/reftable/writer.c @@ -254,7 +254,8 @@ static int writer_index_hash(struct reftable_writer *w, struct reftable_buf *has if (key->offset_len > 0 && key->offsets[key->offset_len - 1] == off) return 0; - REFTABLE_ALLOC_GROW(key->offsets, key->offset_len + 1, key->offset_cap); + REFTABLE_ALLOC_GROW_OR_NULL(key->offsets, key->offset_len + 1, + key->offset_cap); if (!key->offsets) return REFTABLE_OUT_OF_MEMORY_ERROR; key->offsets[key->offset_len++] = off; @@ -820,7 +821,7 @@ static int writer_flush_nonempty_block(struct reftable_writer *w) * Note that this also applies when flushing index blocks, in which * case we will end up with a multi-level index. */ - REFTABLE_ALLOC_GROW(w->index, w->index_len + 1, w->index_cap); + REFTABLE_ALLOC_GROW_OR_NULL(w->index, w->index_len + 1, w->index_cap); if (!w->index) return REFTABLE_OUT_OF_MEMORY_ERROR; From patchwork Wed Dec 25 18:38:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ren=C3=A9_Scharfe?= X-Patchwork-Id: 13920849 Received: from mout.web.de (mout.web.de [212.227.17.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DF97313A868 for ; Wed, 25 Dec 2024 18:38:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=212.227.17.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735151926; cv=none; b=ElLQxzI3gediyW9hjMqKIpSbIsQ7lAcaxlqyu+M93zxGLqZO2GyoVLwR/YxEExnmjhpWWaz/nASa6N1MaLxwgWgNZlYS4zBIplh6N95BRvXQFcobfwSqAED5Yo3XyvUUBf6+5E7awH0U1AXYPlnB5yCTufFPYeTk9rewllo4Yp0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735151926; c=relaxed/simple; bh=Z/JHz+z7FIsXGx+68zxNZULhRvRrrpElyuuK79vRy54=; h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: In-Reply-To:Content-Type; b=kg3WaopPenKWkGv1Va1ggTmqdCcZzgguRjhbz0dHD9ZiYznzEcqlvHbVTFynDKzJRbP1Wuh378LiHpj113xLBvfjUTbd2T8vlS583GPtjEncerxslQoHKZoOReyQN+jaX4txrC8A8ZEipeyF/pGa/T1JxcN84+xhdLLrPVoVVL4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de; spf=pass smtp.mailfrom=web.de; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b=GQCEjvrR; arc=none smtp.client-ip=212.227.17.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=web.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b="GQCEjvrR" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=web.de; s=s29768273; t=1735151916; x=1735756716; i=l.s.r@web.de; bh=k/f7vCIueZLUj1+/OP+ajP3BwxoOcliJCPq0CbxABq8=; h=X-UI-Sender-Class:Message-ID:Date:MIME-Version:Subject:From:To: Cc:References:In-Reply-To:Content-Type:Content-Transfer-Encoding: cc:content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=GQCEjvrRuvtZCPfPOrl8/w85sLIsVhlBqLpE7Oq9EiF9uiGqPiZ+79AiYiXamFUk GhPTjQ7/QqRB8Ael8C2kAMdPThnM2F+11Typz87q1e0JSWm/R6J+RyCZxvub6hmdq hr5FfgogTSGHLaNDck5UR4wmNmPazYtFMx3jwaBMkPjhJBEO/jF18cHACdDCns47c VwTANakl7BS3wQUtk2Fu4PM+bFEwV3H5RMvLXH92MwAz4Nm6l2EHY/Ussg9FwmT+s EvEAo49LjurcVegLniRjQySixpndDhqMAhWFBm5bPJQOug86APpP3bR/wLcTTNDxk 5EWk5vP7G0gfb9lIJQ== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [192.168.178.29] ([79.203.20.45]) by smtp.web.de (mrweb105 [213.165.67.124]) with ESMTPSA (Nemesis) id 1M4bUq-1tPyZx46ru-001fbm; Wed, 25 Dec 2024 19:38:36 +0100 Message-ID: <33bbacc7-1727-4efd-9cbf-3c9abfa94d8c@web.de> Date: Wed, 25 Dec 2024 19:38:35 +0100 Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 2/4] reftable: fix allocation count on realloc error From: =?utf-8?q?Ren=C3=A9_Scharfe?= To: Git List Cc: Patrick Steinhardt References: <2b9fba8d-be63-4145-9d25-a2151e422cfa@web.de> Content-Language: en-US In-Reply-To: <2b9fba8d-be63-4145-9d25-a2151e422cfa@web.de> X-Provags-ID: V03:K1:RsUfda+umVSM49EO9ljw3kt2DwVFqxdyfCt0OibJOtIFFna5uxR aAvGrr+XKPzvJKxxOVKi8EjS3Q8Dau5fdwEnJqXfaoxX3bZBsytx6F6aknvbFLzHub4d2jd pOr8y/0+Oud+d0Uv41eL/Le7LlU/YQwCHpj4M9ipJV6bsJPVi+WxbrMdiOQF21hdDX7FWME eXIsILJHXbMrxUM8mHJ1A== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:/26J9k6uNjg=;+KXNAUCtz/2KTHw9Q/AQjsZp7YT c9JcJo+D9RueUsAfITXgtMQ172v3V+zGhPwOrnxA3Y+ky+krxVssKlb1YycWxp7svvjbMckoq maroKAra9DmWvTdFYfpaVq9PE63W63JcQXe/106hnGC8JHHqphIKTH8WEiHFlPtOKWW8B6b77 xw9DxOmim2eDzhpgYg3+CBUxjKFiURZC8Q6y9pSCpWgXOGCduuwdZmQFnOxWFFRhwjfno5zfI tb9hL6dBPGyLh2Eh+hEEkOrEqE9DU/N+r2/YqIH4uSV3GZt2RBpJ//x/mTJRQqPIXZRZ62Wd+ TxF8gjPXn24iTmdOfxaKYjY1dSm/4MtlmXN4MveqI0RCig+34QgnQieQt/3vyz76gIhlz5rJJ rZgHF5bCqr8S68dfmCGX3x4uqwJobEuN+EP+TtBI8TDcc/Px5WUZ1AHaIFhsrgY7RsaUwrb1M lSHkOppQTzwq8P2sEkQ7tgCLn38ZHq/vDWXLkco+mh3g30YIzA8AMUE92l86EjWWKeTjNk0lP JN7NliW88bGoAS0RSpsljUn8qX5qYKYaIzSuwHBy3gz5HucGhJjWF6Mo2QzCh3IX9rQiMJ/5f /axiSTpUw0Tw1hP8a0C+bBwHRotKniOmECobKvrBM2pnpVWE+ol5cXHrY/aiyICkGI4ZCEypV LY7WYnTPPtJJoOXgupT4GblV/TWXtA8nBgipFLGABYZ+A0p2Ft0I/eSvP+lPAnEdNtF7dy3Fq W6A/mWCAKn/fF4LZ6IidiyfKY03sqT65QIf0X2aRL9DFDXKISh5GcUa6MB/nxWJGQyi0Jrqa/ Zc8xovb9SPVkvVmKF5E9WgOfgGliv5bKHQ8bSsYgJSREMtCBbfg2d85Mim/Ri7MLO8bl+JfpB Y0ibZJJRGYdjIoY36nHA2TMkGYEXAZZ8ICaujTPGhJc3s9CWtbFpfzPsHMZ85kaIGCSHhGLNY IvDaZ7Ih/UTAwprh9all7d9amtb9ftfT8EUJeoOPqwilk4owbOFdlbHrEPqaXg+we9AJy3m0U psUaKjZEh/rgPZc7xiipuT4LtFOdYYd8SWOUOGcCBIbdaLYEzNLb7JQIQrl9vlQ+k8mpFUzfu oppbImzg8= When realloc(3) fails, it returns NULL and keeps the original allocation intact. REFTABLE_ALLOC_GROW overwrites both the original pointer and the allocation count variable in that case, simultaneously leaking the original allocation and misrepresenting the number of storable items. parse_names() avoids the leak by keeping the original pointer if reallocation fails, but still increase the allocation count in such a case as if it succeeded. That's OK, because the error handling code just frees everything and doesn't look at names_cap anymore. reftable_buf_add() does the same, but here it is a problem as it leaves the reftable_buf in a broken state, with ->alloc being roughly twice as big as the actually allocated memory, allowing out-of-bounds writes in subsequent calls. Reimplement REFTABLE_ALLOC_GROW to avoid leaks, keep allocation counts in sync and still signal failures to callers while avoiding code duplication in callers. Make it an expression that evaluates to 0 if no reallocation is needed or it succeeded and 1 on failure while keeping the original pointer and allocation counter values. Adjust REFTABLE_ALLOC_GROW_OR_NULL to the new calling convention for REFTABLE_ALLOC_GROW, but keep its support for non-size_t alloc variables for now. Signed-off-by: René Scharfe --- reftable/basics.c | 11 +++-------- reftable/basics.h | 39 ++++++++++++++++++++++++++------------- 2 files changed, 29 insertions(+), 21 deletions(-) -- 2.47.1 diff --git a/reftable/basics.c b/reftable/basics.c index 70b1091d14..cd6b39dbe9 100644 --- a/reftable/basics.c +++ b/reftable/basics.c @@ -124,11 +124,8 @@ int reftable_buf_add(struct reftable_buf *buf, const void *data, size_t len) size_t newlen = buf->len + len; if (newlen + 1 > buf->alloc) { - char *reallocated = buf->buf; - REFTABLE_ALLOC_GROW(reallocated, newlen + 1, buf->alloc); - if (!reallocated) + if (REFTABLE_ALLOC_GROW(buf->buf, newlen + 1, buf->alloc)) return REFTABLE_OUT_OF_MEMORY_ERROR; - buf->buf = reallocated; } memcpy(buf->buf + buf->len, data, len); @@ -233,11 +230,9 @@ char **parse_names(char *buf, int size) next = end; } if (p < next) { - char **names_grown = names; - REFTABLE_ALLOC_GROW(names_grown, names_len + 1, names_cap); - if (!names_grown) + if (REFTABLE_ALLOC_GROW(names, names_len + 1, + names_cap)) goto err; - names = names_grown; names[names_len] = reftable_strdup(p); if (!names[names_len++]) diff --git a/reftable/basics.h b/reftable/basics.h index 259f4c274c..fa5d75868b 100644 --- a/reftable/basics.h +++ b/reftable/basics.h @@ -120,22 +120,35 @@ char *reftable_strdup(const char *str); #define REFTABLE_ALLOC_ARRAY(x, alloc) (x) = reftable_malloc(st_mult(sizeof(*(x)), (alloc))) #define REFTABLE_CALLOC_ARRAY(x, alloc) (x) = reftable_calloc((alloc), sizeof(*(x))) #define REFTABLE_REALLOC_ARRAY(x, alloc) (x) = reftable_realloc((x), st_mult(sizeof(*(x)), (alloc))) -#define REFTABLE_ALLOC_GROW(x, nr, alloc) \ - do { \ - if ((nr) > alloc) { \ - alloc = 2 * (alloc) + 1; \ - if (alloc < (nr)) \ - alloc = (nr); \ - REFTABLE_REALLOC_ARRAY(x, alloc); \ - } \ - } while (0) + +static inline void *reftable_alloc_grow(void *p, size_t nelem, size_t elsize, + size_t *allocp) +{ + void *new_p; + size_t alloc = *allocp * 2 + 1; + if (alloc < nelem) + alloc = nelem; + new_p = reftable_realloc(p, st_mult(elsize, alloc)); + if (!new_p) + return p; + *allocp = alloc; + return new_p; +} + +#define REFTABLE_ALLOC_GROW(x, nr, alloc) ( \ + (nr) > (alloc) && ( \ + (x) = reftable_alloc_grow((x), (nr), sizeof(*(x)), &(alloc)), \ + (nr) > (alloc) \ + ) \ +) #define REFTABLE_ALLOC_GROW_OR_NULL(x, nr, alloc) do { \ - void *reftable_alloc_grow_or_null_orig_ptr = (x); \ - REFTABLE_ALLOC_GROW((x), (nr), (alloc)); \ - if (!(x)) { \ - reftable_free(reftable_alloc_grow_or_null_orig_ptr); \ + size_t reftable_alloc_grow_or_null_alloc = alloc; \ + if (REFTABLE_ALLOC_GROW((x), (nr), reftable_alloc_grow_or_null_alloc)) { \ + reftable_free(x); \ alloc = 0; \ + } else { \ + alloc = reftable_alloc_grow_or_null_alloc; \ } \ } while (0) From patchwork Wed Dec 25 18:38:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ren=C3=A9_Scharfe?= X-Patchwork-Id: 13920850 Received: from mout.web.de (mout.web.de [217.72.192.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E52441B393B for ; Wed, 25 Dec 2024 18:38:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.72.192.78 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735151928; cv=none; b=tv7ynijHbrSZaulR284oQGO+EDc/wJ8+QAWIuXH+TSdtAPzIHEs3Mv10I9zE5QDS4PYuieGVv/smB+raUVbGlXtwM5DBO0WpXWdeRffZRmPP8UXJ779l5l/zu+7FtDeBjXOFJg8c33WboGQDEVPu6HaYitzSzmoYL2Mj5hDILJ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735151928; c=relaxed/simple; bh=BT3ZlamRjlTQ/Q1prjgXuyg7Xvp7GA+x9fRxobDZtCg=; h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: In-Reply-To:Content-Type; b=hD4V/K7I+CrkrReb3Sq2QSvbbV5HGeH8IXy9tN4hUpnQwBgR7UJZLz7B0fbNi47ZwuHUbGqkeyQfjtfsZHudC/Yu+Ua/XufSJxD8lP7IwuiuAXXBIk2BN9+V8gSNK2UlmIRGoNSXR+rd+toVDzeYhrOUrkCDqq1Xd7bfEXD6pgU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de; spf=pass smtp.mailfrom=web.de; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b=unZFWshl; arc=none smtp.client-ip=217.72.192.78 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=web.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b="unZFWshl" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=web.de; s=s29768273; t=1735151921; x=1735756721; i=l.s.r@web.de; bh=WhvwdGGVHmi193NooQ/nKPF9sG6V7N0tx6bM2/tX8eo=; h=X-UI-Sender-Class:Message-ID:Date:MIME-Version:Subject:From:To: Cc:References:In-Reply-To:Content-Type:Content-Transfer-Encoding: cc:content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=unZFWshlGbMjiXRtB0UdHdzvyVHb02wMDqOftiZK9CriDZe0fGAjanK7Bg4q4N/T EjGWZ5xSOR8tJH0/OnO4UrEFL03w2d9GYQsRO/MaQdYmbM9Uz++nH+9fBjJNHjKjm AAWxzVcBYK3jNEa5XdYWsZuI5O3xSC/MIUU/2wF0gggeC9sIPBTJI/JNnJECFDHwK 74c2/7OcCj4Fwuzs1x1iixMWnnoAC+k/+aTR+AWzX4KXEDucKMAEQ0idsbESag37b 1uZ4y4UV3IJd+LUH/Nl4QCm1Bc2XtE7Sr9WNH1zvdHax03EucLSNZ8wK3KD0bVSf0 UPpbV8bcYPMOC0mXqg== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [192.168.178.29] ([79.203.20.45]) by smtp.web.de (mrweb105 [213.165.67.124]) with ESMTPSA (Nemesis) id 1MDv9a-1tGeuL0CSi-009x56; Wed, 25 Dec 2024 19:38:41 +0100 Message-ID: <3ca514b7-63f8-49cb-9816-627d706c6145@web.de> Date: Wed, 25 Dec 2024 19:38:40 +0100 Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 3/4] reftable: handle realloc error in parse_names() From: =?utf-8?q?Ren=C3=A9_Scharfe?= To: Git List Cc: Patrick Steinhardt References: <2b9fba8d-be63-4145-9d25-a2151e422cfa@web.de> Content-Language: en-US In-Reply-To: <2b9fba8d-be63-4145-9d25-a2151e422cfa@web.de> X-Provags-ID: V03:K1:UKfeXkiqWp1TfpRxbfbodlnI3EkOcVKqdqdSVm0tV/ReUBZ5oWx hgVpgxgaYKuij3DHKFbpk+IyzxvN4oZdEFDPiVRNYKV2BAh4CWKcjIa1ofl1u4/twJTKzbX ZE2jyJar7CV0T1QXSAOnL42Raw7GstDb/OEyk8XWCjeNiDW7EyTBRDpenA9Et17FLXj4rjV jvt/1YSD0d7sQRo3g6Yuw== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:OT/lZ/65q9Y=;cymI3Bzn6C0YTyYX9vwyPCr2beW Ag/AAbeDQBqpov551gvKEna5ebtmM0nv5QzQe7WqxhrzduZ0TyJqSLyR9Rix1HJ64m7Y9AcSC YXv5MmQLENzmdTIS70KSBs9q+T5N+GgF1VliLzbtyCiqfcZy2b98vXjONuIUitYxzT7aZ7/ms V9sLrcNy6ZeeDEN4kDrtTErmyBzmXfmidPD0YOJa1914XGB9kvqTR0nPo6efrD71+kgx8+ljC Xcwcdn/jc4I6YVm2zuO3931LGrHHgMlisFYDoLEjFCOMaGCIyUOSPKvU4oBw4GMxh/mnMrrWN ZuNHm/pbsjpoVVxdAs23moDoS5Pi8d+3p0Olq+WLF80uVoihqp8qAFG5/aFlc2Au469pJLaHl 6OMC8SlqnkslqiZQNqnIQDUEw1MXhj4mMqMBWEBdeLsDobdwSmrmmZa7lFtELsUGBHBQisRZz zWV7FQ1Ac3UET6pS4PyoHGkEDWZ8gXFsJxteQNxose5EDgweb+uYOu8R7/CRAxs3qWYteCkOR kKY5CIi6WHdEDouTAlYhBjU1LvFnjwv80hAcnrsutoi5WwD3OijCyHytZCG1/VsxujKNfDJTc CZOjbIYamdqDqbUtHEEh9MLQRciIoYkVCzhHt/Gq4CIs0RmWD4H0ggv7CaUeJQvHkXtCbGSAD 0xipBn86avDy8gVweJen3cb0zVBotWJlwXxoyPrdt46tIFGzDJkQeomkEWnDgAwpPN+7ofn0b AO/NYwnL5ZedTxlSQNayKRrdagc7vxDwlfmPcVq//Z3sKztIuTQt1Q+UXt7dhsDQyFQ1hqaQn ZxvPiRZ1/A0NWbz72Bf3smaybKBKKgsRscwAZcTJnpReIfH1CxOHGTM+oazAd1ocZL+TlLa3f CLarVxV0r+axmYnh0CbdwDnL36/C0Steu9WCHFJfSP//V3OyC99ep6r804Exk4QfGe58rx4aR OFpfDsjVtR0UZfEos0UYLpKKOHA6HI/xjOa6KzU7UXGRFHZdOoL835KMdvArAPKQeDBTFyWuS 8H7YsTVGUoVgxVuwo1GPGtRcq+cOxFqAlYzGK9YoKgFRi7dyDv+11JlECwr0MMdit4lIfy0mx d/OktxbHM= Check the final reallocation for adding the terminating NULL and handle it just like those in the loop. Simply use REFTABLE_ALLOC_GROW instead of keeping the REFTABLE_REALLOC_ARRAY call and adding code to preserve the original pointer value around it. Signed-off-by: René Scharfe --- reftable/basics.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) -- 2.47.1 diff --git a/reftable/basics.c b/reftable/basics.c index cd6b39dbe9..fe2b83ff83 100644 --- a/reftable/basics.c +++ b/reftable/basics.c @@ -241,7 +241,8 @@ char **parse_names(char *buf, int size) p = next + 1; } - REFTABLE_REALLOC_ARRAY(names, names_len + 1); + if (REFTABLE_ALLOC_GROW(names, names_len + 1, names_cap)) + goto err; names[names_len] = NULL; return names; From patchwork Wed Dec 25 18:38:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ren=C3=A9_Scharfe?= X-Patchwork-Id: 13920851 Received: from mout.web.de (mout.web.de [212.227.17.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D237E22615 for ; Wed, 25 Dec 2024 18:38:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=212.227.17.11 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735151936; cv=none; b=HgnpBPVQFjhYMLNrStOWeI6AAGOio3AJVNBH6gOLWyAJw2G2X+zpH5FM/Yn269HKRTaoyys3qU6npSvqbRWKyk8Jv0BOm3tyQEOT6oT7w15s+XI22PpjpL//6TcuFr9HAZW29P7E7cdGSf3EibfpCot9cs1U2I2eccl+iKjmf8E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735151936; c=relaxed/simple; bh=AMvxWrJKXlKe7act6hJa8/4dxI7g1era30ZozgVAgIk=; h=Message-ID:Date:MIME-Version:Subject:From:To:Cc:References: In-Reply-To:Content-Type; b=eRCrvffleCZPo8bpUV51Qn455OA0wjgufmq1k2KMEzDST/yKkF7KMH8pe1V0FxV14KodB8TlZxPCRGHLecAea9+fv85sqfECjwxQonFg2EmZNWgxskjIAp521ccnIIOLjxCMNtpBJy3AirSEBdd9y6iNRYoQYUv25+cgWj5CAaI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de; spf=pass smtp.mailfrom=web.de; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b=uEWpC5qq; arc=none smtp.client-ip=212.227.17.11 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=web.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=web.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=web.de header.i=l.s.r@web.de header.b="uEWpC5qq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=web.de; s=s29768273; t=1735151930; x=1735756730; i=l.s.r@web.de; bh=BHk3O0sM//TK8QWaIGxz1AQbFuItjLHdy8eY9u1Bj/o=; h=X-UI-Sender-Class:Message-ID:Date:MIME-Version:Subject:From:To: Cc:References:In-Reply-To:Content-Type:Content-Transfer-Encoding: cc:content-transfer-encoding:content-type:date:from:message-id: mime-version:reply-to:subject:to; b=uEWpC5qqhhcuPTmqTKENDAWvzBR+9PECEDdGxTwsHfNjVw7MQKt2ahCbbJz4uBEg 13iXg7y4m0a1i2ay7HC8ueEVir68rVPJC9S11IYTnbfzYwMZ06ukG9CQzCr/Poawc 8rlv6Y1NxlysK6FbtgUtJwHMWrnMv3gZv+hymX1JjE6WyPFvCmnNrwQp2ICFwOjkS XYX3YNq1JNvNcH8nX7sd7FYRtXEknYSZd3PmFcS6CjcH9WLon3lNgpQPfbHLV15W7 +Anr91zv+UqhyM79RwhnBzFj7ZRPbjxfq7Jcy7eb11jRKFjcBv7hCZafRyS1I+qCC XclGP3IHRdilcaUXrg== X-UI-Sender-Class: 814a7b36-bfc1-4dae-8640-3722d8ec6cd6 Received: from [192.168.178.29] ([79.203.20.45]) by smtp.web.de (mrweb105 [213.165.67.124]) with ESMTPSA (Nemesis) id 1N62uQ-1tbc8I0SZE-016Row; Wed, 25 Dec 2024 19:38:50 +0100 Message-ID: <6084c017-9557-478b-b485-a1c1a21842e7@web.de> Date: Wed, 25 Dec 2024 19:38:49 +0100 Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH 4/4] t-reftable-merged: check realloc errors From: =?utf-8?q?Ren=C3=A9_Scharfe?= To: Git List Cc: Patrick Steinhardt References: <2b9fba8d-be63-4145-9d25-a2151e422cfa@web.de> Content-Language: en-US In-Reply-To: <2b9fba8d-be63-4145-9d25-a2151e422cfa@web.de> X-Provags-ID: V03:K1:rDljamnGyIvyYxt+Ot7PpKMf6hyLFgg/5awLj47J5WAzf0oQczX Ym8aHaEi6GpzQdXqxHcWKuD8DqjfLj7r67XiD7+W7UV9uTyeeP5z/caYZgvjJOQKWuVk42U jRXL5amzEDFG0od8Yds/IB9vN6cme+jswhxJksYMu6FHKCwl2KVbwM+j45KNhTz7Cq6h38Y 2nfsBBMB/xX/dgxaVfdJg== X-Spam-Flag: NO UI-OutboundReport: notjunk:1;M01:P0:7wwFwaqJFrc=;mje3eUYmiiBuiVYyxqaqkzo8GJG h/T2+gHR3df4MAuHECkzyQWKuFSMEy9DrnTy7IXQtg/6gDwKdOB6QmrA14vjOKsqQOvYtiFuA 1n1vzlgJa0/U9H2RoPv+oUooXhoKPZO8x3waIU93/xyZaLl8dertK/N3JZJr5xOxvflE1ZRRM f4TyTN5rW38RL71W4ZyBNs2Hg3ofIGF/MM+C0XdorBf0xidT2schepvfUZZ2D35NiFJnex+lv tvotitkiZqpiK+o8AtXlhJSb+B1PgZpyJbmMsWmsCJSZzu1MFvFH9is8bmQwkWcGH1qkN45v8 li16dGpvJjuGCU20y7u+Md71Afu3bzevVG8LMcM0XaBPle303QjG0BVtuHBiTIxctXw5C0W2n pZ5M77HKwLPSPC6Am70e+fbwLu4pZzf/4+8r2OiiUCq4UBBxW6C1MQIBQEy2MZ9O4kRddnWGR i39+J6HO2C9Ooi2UX/hrJTzKgF9gnZh6IqigKbn/TAYPCDekLT34KugikcsimkXYfDifLRAg1 NeXki8Wly/ANOZ5+UY10byMCTp1Ar68J4of/QoI4ZEo7zXZMmbdzhDlB1P/a5aCRWnscctHly 2hiFKKrnha7TiXi5ZUZ4hUPVOrpPHw8TR9Ob6WEvka2dyJDznBBJHYOt1TzOSbhXkl+JESfab uqKJi93KkH1nk008VeUifOurosRUX/OeOc7ExgQHJoJ20P705FGcfjfSNFI6q2tbzB0gL63F3 ld8sbW+Wr2FT2/4hn80y/ZeYd6iSed9UFF2NcJi1OUmnxI00Sg4jQrBKMVFASB7/LOPEIRuI7 4MJ1TQNpAcReUqfD0qRvPpm8AnBoeNuzJ0/NyJYtgvt0Tze8t5GqUEQhL/QubapFptnwVmQQ7 w9Y8yZQqJ83fidS+1k/NRKuUhN3Epz/Gg0a6hW4Y6DLzaRNYn5CyAX7WDttKVq3bJb0CieA34 uxU3DZ+K6usvUIqgExUnX0G4uvmC9IFWojFPgKtX41G8upHn7/KGme+Plh6IeAIDPu/EEFKem MRzCP5DZHDidA2vvY19WkvHUnuDnVwJ7GcoxcqypEODdfgEpAxfiKCXbXjRAllyMUyfP+C207 zW39QSCv8= Report reallocation errors in unit tests, like everywhere else. Signed-off-by: René Scharfe --- t/unit-tests/t-reftable-merged.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) -- 2.47.1 diff --git a/t/unit-tests/t-reftable-merged.c b/t/unit-tests/t-reftable-merged.c index a12bd0e1a3..60836f80d6 100644 --- a/t/unit-tests/t-reftable-merged.c +++ b/t/unit-tests/t-reftable-merged.c @@ -178,7 +178,7 @@ static void t_merged_refs(void) if (err > 0) break; - REFTABLE_ALLOC_GROW(out, len + 1, cap); + check(!REFTABLE_ALLOC_GROW(out, len + 1, cap)); out[len++] = ref; } reftable_iterator_destroy(&it); @@ -459,7 +459,7 @@ static void t_merged_logs(void) if (err > 0) break; - REFTABLE_ALLOC_GROW(out, len + 1, cap); + check(!REFTABLE_ALLOC_GROW(out, len + 1, cap)); out[len++] = log; } reftable_iterator_destroy(&it);