Skip to content

Commit ca63af0

Browse files
pks-tgitster
authored andcommitted
reftable/stack: fix parameter validation when compacting range
The `stack_compact_range()` function receives a "first" and "last" index that indicates which tables of the reftable stack should be compacted. Naturally, "first" must be smaller than "last" in order to identify a proper range of tables to compress, which we indeed also assert in the function. But the validations happens after we have already allocated arrays with a size of `last - first + 1`, leading to an underflow and thus an invalid allocation size. Fix this by reordering the array allocations to happen after we have validated parameters. While at it, convert the array allocations to use the newly introduced macros. Note that the relevant variables pointing into arrays should also be converted to use `size_t` instead of `int`. This is left for a later commit in this series. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b4ff12c commit ca63af0

File tree

1 file changed

+13
-11
lines changed

1 file changed

+13
-11
lines changed

reftable/stack.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -966,6 +966,7 @@ static int stack_write_compact(struct reftable_stack *st,
966966
static int stack_compact_range(struct reftable_stack *st, int first, int last,
967967
struct reftable_log_expiry_config *expiry)
968968
{
969+
char **delete_on_success = NULL, **subtable_locks = NULL, **listp = NULL;
969970
struct strbuf temp_tab_file_name = STRBUF_INIT;
970971
struct strbuf new_table_name = STRBUF_INIT;
971972
struct strbuf lock_file_name = STRBUF_INIT;
@@ -974,12 +975,7 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last,
974975
int err = 0;
975976
int have_lock = 0;
976977
int lock_file_fd = -1;
977-
int compact_count = last - first + 1;
978-
char **listp = NULL;
979-
char **delete_on_success =
980-
reftable_calloc(compact_count + 1, sizeof(*delete_on_success));
981-
char **subtable_locks =
982-
reftable_calloc(compact_count + 1, sizeof(*subtable_locks));
978+
int compact_count;
983979
int i = 0;
984980
int j = 0;
985981
int is_empty_table = 0;
@@ -989,6 +985,10 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last,
989985
goto done;
990986
}
991987

988+
compact_count = last - first + 1;
989+
REFTABLE_CALLOC_ARRAY(delete_on_success, compact_count + 1);
990+
REFTABLE_CALLOC_ARRAY(subtable_locks, compact_count + 1);
991+
992992
st->stats.attempts++;
993993

994994
strbuf_reset(&lock_file_name);
@@ -1146,12 +1146,14 @@ static int stack_compact_range(struct reftable_stack *st, int first, int last,
11461146
done:
11471147
free_names(delete_on_success);
11481148

1149-
listp = subtable_locks;
1150-
while (*listp) {
1151-
unlink(*listp);
1152-
listp++;
1149+
if (subtable_locks) {
1150+
listp = subtable_locks;
1151+
while (*listp) {
1152+
unlink(*listp);
1153+
listp++;
1154+
}
1155+
free_names(subtable_locks);
11531156
}
1154-
free_names(subtable_locks);
11551157
if (lock_file_fd >= 0) {
11561158
close(lock_file_fd);
11571159
lock_file_fd = -1;

0 commit comments

Comments
 (0)