Skip to content

Commit 3dfd305

Browse files
dschogitster
authored andcommitted
fsmonitor: fix memory corruption in some corner cases
In 56c6910 (fsmonitor: change last update timestamp on the index_state to opaque token, 2020-01-07), we forgot to adjust the part of `unpack_trees()` that copies the FSMonitor "last-update" information that we copy from the source index to the result index since 679f2f9 (unpack-trees: skip stat on fsmonitor-valid files, 2019-11-20). Since the "last-update" information is no longer a 64-bit number, but a free-form string that has been allocated, we need to duplicate it rather than just copying it. This is important because there _are_ cases when `unpack_trees()` will perform a oneway merge that implicitly calls `refresh_fsmonitor()` (which will allocate that "last-update" token). This happens _after_ that token was copied into the result index. However, we _then_ call `check_updates()` on that index, which will _also_ call `refresh_fsmonitor()`, accessing the "last-update" string, which by now would be released already. In the instance that lead to this patch, this caused a segmentation fault during a lengthy, complicated rebase involving the todo command `reset` that (crucially) had to updated many files. Unfortunately, it seems very hard to trigger that crash, therefore this patch is not accompanied by a regression test. Signed-off-by: Johannes Schindelin <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 94f6e3e commit 3dfd305

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

unpack-trees.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,8 +1614,8 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
16141614
o->merge_size = len;
16151615
mark_all_ce_unused(o->src_index);
16161616

1617-
if (o->src_index->fsmonitor_last_update)
1618-
o->result.fsmonitor_last_update = o->src_index->fsmonitor_last_update;
1617+
o->result.fsmonitor_last_update =
1618+
xstrdup_or_null(o->src_index->fsmonitor_last_update);
16191619

16201620
/*
16211621
* Sparse checkout loop #1: set NEW_SKIP_WORKTREE on existing entries

0 commit comments

Comments
 (0)