diff options
author | Junio C Hamano <gitster@pobox.com> | 2023-03-02 15:13:30 -0800 |
---|---|---|
committer | Johannes Schindelin <johannes.schindelin@gmx.de> | 2023-04-17 21:15:41 +0200 |
commit | 18e2b1cfc80990719275d7b08e6e50f3e8cbc902 (patch) | |
tree | 20f2b635d2612ce45fd88178a0012d884f667795 | |
parent | 2f3b28f27234a0130583131a6785c44e3dd1cac4 (diff) | |
parent | 9db05711c98efc14f414d4c87135a34c13586e0b (diff) | |
download | git-18e2b1cfc80990719275d7b08e6e50f3e8cbc902.tar.gz |
Merge branch 'js/apply-overwrite-rej-symlink-if-exists' into maint-2.30
Address CVE-2023-25652 by deleting any existing `.rej` symbolic links
instead of following them.
* js/apply-overwrite-rej-symlink-if-exists:
apply --reject: overwrite existing `.rej` symlink if it exists
Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
-rw-r--r-- | apply.c | 14 | ||||
-rwxr-xr-x | t/t4115-apply-symlink.sh | 15 |
2 files changed, 27 insertions, 2 deletions
@@ -4558,7 +4558,7 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch) FILE *rej; char namebuf[PATH_MAX]; struct fragment *frag; - int cnt = 0; + int fd, cnt = 0; struct strbuf sb = STRBUF_INIT; for (cnt = 0, frag = patch->fragments; frag; frag = frag->next) { @@ -4598,7 +4598,17 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch) memcpy(namebuf, patch->new_name, cnt); memcpy(namebuf + cnt, ".rej", 5); - rej = fopen(namebuf, "w"); + fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666); + if (fd < 0) { + if (errno != EEXIST) + return error_errno(_("cannot open %s"), namebuf); + if (unlink(namebuf)) + return error_errno(_("cannot unlink '%s'"), namebuf); + fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666); + if (fd < 0) + return error_errno(_("cannot open %s"), namebuf); + } + rej = fdopen(fd, "w"); if (!rej) return error_errno(_("cannot open %s"), namebuf); diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh index 14e0f4d705..2d03c4e4d1 100755 --- a/t/t4115-apply-symlink.sh +++ b/t/t4115-apply-symlink.sh @@ -125,4 +125,19 @@ test_expect_success SYMLINKS 'symlink escape when deleting file' ' test_path_is_file .git/delete-me ' +test_expect_success SYMLINKS '--reject removes .rej symlink if it exists' ' + test_when_finished "git reset --hard && git clean -dfx" && + + test_commit file && + echo modified >file.t && + git diff -- file.t >patch && + echo modified-again >file.t && + + ln -s foo file.t.rej && + test_must_fail git apply patch --reject 2>err && + test_i18ngrep "Rejected hunk" err && + test_path_is_missing foo && + test_path_is_file file.t.rej +' + test_done |