[PATCH 5/6] notes: avoid truncating the size of concatenated notes
- From
Elia Pinto <gitter.spiros@gmail.com>
- Date
- Oct 30, 2026, 10:28 UTC
- Message-ID
- <21f5a4e009155e36865f6b01d59a00b644669e41.1793355390.git.gitter.spiros@gmail.com>
- In-Reply-To
- <cover.1793355390.git.gitter.spiros@gmail.com>
combine_notes_concatenate() reads both notes with odb_read_object(), which returns their sizes as size_t, but computes the size of the combined buffer in an "unsigned long". On platforms where that type is 32 bits wide, like Windows, two notes adding up to 4GiB or more give a small buf_len: we allocate that many bytes and then memcpy() the full contents of both notes into the buffer, writing far past its end.
The notes can come from a fetched notes ref. Besides notes merges with the "union" strategy and notes.rewriteMode=concatenate (the default), the function is also used when loading a notes tree that contains more than one note for the same object, e.g. at different fanout levels, so merely displaying such notes is enough to trigger it.
Compute the size as a size_t with st_add3(), and go through cast_size_t_to_ulong() when passing it to odb_write_object(), whose length parameter is still an "unsigned long". That makes us die on such platforms instead of writing a truncated blob, until the write API learns about size_t, too.
No test, as triggering this needs a platform with a 32-bit "long" and notes larger than 4GiB.
Signed-off-by: Elia Pinto <gitter.spiros@gmail.com> --- notes.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/notes.c b/notes.c index ec9c2cb150..05da28b8d4 100644 --- a/notes.c +++ b/notes.c @@ -811,8 +811,7 @@ int combine_notes_concatenate(struct object_id *cur_oid, const struct object_id *new_oid) { char *cur_msg = NULL, *new_msg = NULL, *buf; - unsigned long buf_len; - size_t cur_len, new_len; + size_t cur_len, new_len, buf_len; enum object_type cur_type, new_type; int ret; @@ -839,7 +838,7 @@ int combine_notes_concatenate(struct object_id *cur_oid, cur_len--; /* concatenate cur_msg and new_msg into buf */ - buf_len = cur_len + 2 + new_len; + buf_len = st_add3(cur_len, 2, new_len); buf = (char *) xmalloc(buf_len); memcpy(buf, cur_msg, cur_len); buf[cur_len] = '\n'; @@ -850,7 +849,7 @@ int combine_notes_concatenate(struct object_id *cur_oid, /* create a new blob object from buf */ ret = odb_write_object(the_repository->objects, buf, - buf_len, OBJ_BLOB, cur_oid); + cast_size_t_to_ulong(buf_len), OBJ_BLOB, cur_oid); free(buf); return ret; }
-- 2.53.0