Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Thiel <sebastian.thiel@icloud.com>2023-08-09 10:47:41 +0300
committerJunio C Hamano <gitster@pobox.com>2023-08-09 21:46:12 +0300
commit72695d8214791161a943086e894874b4fd71ba9f (patch)
treeca6ce6929e54f372f3a5a26ef1b1ffc3a262430b /builtin/mv.c
parentfb7d80edcae482f4fa5d4be0227dc3054734e5f3 (diff)
mv: handle lstat() failure correctly
When moving a directory onto another with `git mv` various checks are performed. One of of these validates that the destination is not existing. When calling `lstat` on the destination path and it fails as the path doesn't exist, some environments seem to overwrite the passed in `stat` memory nonetheless (I observed this issue on debian 12 of x86_64, running on OrbStack on ARM, emulated with Rosetta). This would affect the code that followed as it would still acccess a now modified `st` structure, which now seems to contain uninitialized memory. `S_ISDIR(st_dir_mode)` would then typically return false causing the code to run into a bad case. The fix avoids overwriting the existing `st` structure, providing an alternative that exists only for that purpose. Note that this patch minimizes complexity instead of stack-frame size. Signed-off-by: Sebastian Thiel <sebastian.thiel@icloud.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/mv.c')
-rw-r--r--builtin/mv.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/builtin/mv.c b/builtin/mv.c
index 665bd27448..5213d99381 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -183,7 +183,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
int src_dir_nr = 0, src_dir_alloc = 0;
struct strbuf a_src_dir = STRBUF_INIT;
enum update_mode *modes, dst_mode = 0;
- struct stat st;
+ struct stat st, dest_st;
struct string_list src_for_dst = STRING_LIST_INIT_NODUP;
struct lock_file lock_file = LOCK_INIT;
struct cache_entry *ce;
@@ -303,7 +303,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
goto act_on_entry;
}
if (S_ISDIR(st.st_mode)
- && lstat(dst, &st) == 0) {
+ && lstat(dst, &dest_st) == 0) {
bad = _("cannot move directory over file");
goto act_on_entry;
}