Skip to content

Commit f11f0a5

Browse files
KarthikNayakgitster
authored andcommitted
refs/reftable: fix uninitialized memory access of max_index
When migrating reflogs between reference backends, maintaining the original order of the reflog entries is crucial. To achieve this, an `index` field is stored within the `ref_update` struct that encodes the relative order of reflog entries. This field is used by the reftable backend as update index for the respective reflog entries to maintain that ordering. These update indices must be respected when writing table headers, which encode the minimum and maximum update index of contained records in the header and footer. This logic was added in commit bc67b4a (reftable: write correct max_update_index to header, 2025-01-15), which started to use `reftable_writer_set_limits()` to propagate the mininum and maximum update index of all records contained in a ref transaction. However, we only set the maximum update index for the first transaction argument, even though there can be multiple such arguments. This is the case when we write to multiple stacks in a single transaction, e.g. when updating references in two different worktrees at once. Consequently, the update index for all but the first argument remain uninitialized, which may cause undefined behaviour. Fix this by moving the assignment of the maximum update index in `reftable_be_transaction_finish()` inside the loop, which ensures that all elements of the array are correctly initialized. Furthermore, initialize the `max_index` field to 0 when queueing a new transaction argument. This is not strictly necessary, as all elements of `write_transaction_table_arg.max_index` are now assigned correctly. However, this initialization is added for consistency and to safeguard against potential future changes that might inadvertently introduce uninitialized memory access. Reported-by: Johannes Schindelin <[email protected]> Signed-off-by: Karthik Nayak <[email protected]> Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bc67b4a commit f11f0a5

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

refs/reftable-backend.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,7 @@ static int prepare_transaction_update(struct write_transaction_table_arg **out,
920920
arg->updates_nr = 0;
921921
arg->updates_alloc = 0;
922922
arg->updates_expected = 0;
923+
arg->max_index = 0;
923924
}
924925

925926
arg->updates_expected++;
@@ -1502,10 +1503,9 @@ static int reftable_be_transaction_finish(struct ref_store *ref_store UNUSED,
15021503
struct reftable_transaction_data *tx_data = transaction->backend_data;
15031504
int ret = 0;
15041505

1505-
if (tx_data->args)
1506-
tx_data->args->max_index = transaction->max_index;
1507-
15081506
for (size_t i = 0; i < tx_data->args_nr; i++) {
1507+
tx_data->args[i].max_index = transaction->max_index;
1508+
15091509
ret = reftable_addition_add(tx_data->args[i].addition,
15101510
write_transaction_table, &tx_data->args[i]);
15111511
if (ret < 0)

0 commit comments

Comments
 (0)