Git fork

Sync with 2.39.3

* maint-2.39: (34 commits)
Git 2.39.3
Git 2.38.5
Git 2.37.7
Git 2.36.6
Git 2.35.8
Makefile: force -O0 when compiling with SANITIZE=leak
Git 2.34.8
Git 2.33.8
Git 2.32.7
Git 2.31.8
tests: avoid using `test_i18ncmp`
Git 2.30.9
gettext: avoid using gettext if the locale dir is not present
apply --reject: overwrite existing `.rej` symlink if it exists
http.c: clear the 'finished' member once we are done with it
clone.c: avoid "exceeds maximum object size" error with GCC v12.x
t5604: GETTEXT_POISON fix, conclusion
t5604: GETTEXT_POISON fix, part 1
t5619: GETTEXT_POISON fix
range-diff: use ssize_t for parsed "len" in read_patches()
...

+200 -16
+43
Documentation/RelNotes/2.30.9.txt
··· 1 + Git v2.30.9 Release Notes 2 + ========================= 3 + 4 + This release addresses the security issues CVE-2023-25652, 5 + CVE-2023-25815, and CVE-2023-29007. 6 + 7 + 8 + Fixes since v2.30.8 9 + ------------------- 10 + 11 + * CVE-2023-25652: 12 + 13 + By feeding specially crafted input to `git apply --reject`, a 14 + path outside the working tree can be overwritten with partially 15 + controlled contents (corresponding to the rejected hunk(s) from 16 + the given patch). 17 + 18 + * CVE-2023-25815: 19 + 20 + When Git is compiled with runtime prefix support and runs without 21 + translated messages, it still used the gettext machinery to 22 + display messages, which subsequently potentially looked for 23 + translated messages in unexpected places. This allowed for 24 + malicious placement of crafted messages. 25 + 26 + * CVE-2023-29007: 27 + 28 + When renaming or deleting a section from a configuration file, 29 + certain malicious configuration values may be misinterpreted as 30 + the beginning of a new configuration section, leading to arbitrary 31 + configuration injection. 32 + 33 + Credit for finding CVE-2023-25652 goes to Ry0taK, and the fix was 34 + developed by Taylor Blau, Junio C Hamano and Johannes Schindelin, 35 + with the help of Linus Torvalds. 36 + 37 + Credit for finding CVE-2023-25815 goes to Maxime Escourbiac and 38 + Yassine BENGANA of Michelin, and the fix was developed by Johannes 39 + Schindelin. 40 + 41 + Credit for finding CVE-2023-29007 goes to André Baptista and Vítor Pinho 42 + of Ethiack, and the fix was developed by Taylor Blau, and Johannes 43 + Schindelin, with help from Jeff King, and Patrick Steinhardt.
+6
Documentation/RelNotes/2.31.8.txt
··· 1 + Git v2.31.8 Release Notes 2 + ========================= 3 + 4 + This release merges the fixes that appear in v2.30.9 to address the 5 + security issues CVE-2023-25652, CVE-2023-25815, and CVE-2023-29007; 6 + see the release notes for that version for details.
+7
Documentation/RelNotes/2.32.7.txt
··· 1 + Git v2.32.7 Release Notes 2 + ========================= 3 + 4 + This release merges the fixes that appear in v2.30.9 and v2.31.8 to 5 + address the security issues CVE-2023-25652, CVE-2023-25815, and 6 + CVE-2023-29007; see the release notes for these versions for 7 + details.
+7
Documentation/RelNotes/2.33.8.txt
··· 1 + Git v2.33.8 Release Notes 2 + ========================= 3 + 4 + This release merges the fixes that appear in v2.30.9, v2.31.8 and 5 + v2.32.7 to address the security issues CVE-2023-25652, 6 + CVE-2023-25815, and CVE-2023-29007; see the release notes for these 7 + versions for details.
+7
Documentation/RelNotes/2.34.8.txt
··· 1 + Git v2.34.8 Release Notes 2 + ========================= 3 + 4 + This release merges the fixes that appear in v2.30.9, v2.31.8, 5 + v2.32.7 and v2.33.8 to address the security issues CVE-2023-25652, 6 + CVE-2023-25815, and CVE-2023-29007; see the release notes for these 7 + versions for details.
+7
Documentation/RelNotes/2.35.8.txt
··· 1 + Git v2.35.8 Release Notes 2 + ========================= 3 + 4 + This release merges the fixes that appear in v2.30.9, v2.31.8, 5 + v2.32.7, v2.33.8 and v2.34.8 to address the security issues 6 + CVE-2023-25652, CVE-2023-25815, and CVE-2023-29007; see the release 7 + notes for these versions for details.
+7
Documentation/RelNotes/2.36.6.txt
··· 1 + Git v2.36.6 Release Notes 2 + ========================= 3 + 4 + This release merges the fixes that appear in v2.30.9, v2.31.8, 5 + v2.32.7, v2.33.8, v2.34.8 and v2.35.8 to address the security issues 6 + CVE-2023-25652, CVS-2023-25815, and CVE-2023-29007; see the release 7 + notes for these versions for details.
+7
Documentation/RelNotes/2.37.7.txt
··· 1 + Git v2.37.7 Release Notes 2 + ========================= 3 + 4 + This release merges up the fix that appears in v2.30.9, v2.31.8, 5 + v2.32.7, v2.33.8, v2.34.8, v2.35.8 and v2.36.6 to address the 6 + security issues CVE-2023-25652, CVE-2023-25815, and CVE-2023-29007; 7 + see the release notes for these versions for details.
+8
Documentation/RelNotes/2.38.5.txt
··· 1 + Git v2.38.5 Release Notes 2 + ========================= 3 + 4 + This release merges up the fix that appears in v2.30.9, v2.31.8, 5 + v2.32.7, v2.33.8, v2.34.8, v2.35.8, v2.36.6 and v2.37.7 to address 6 + the security issues CVE-2023-25652, CVE-2023-25815, and 7 + CVE-2023-29007; see the release notes for these versions for 8 + details.
+9 -3
Documentation/RelNotes/2.39.3.txt
··· 1 1 Git v2.39.3 Release Notes 2 2 ========================= 3 3 4 - This release is primarily to merge fixes accumulated on the 'master' 5 - front to prepare for 2.40 release that are still relevant to 2.39.x 6 - maintenance track. 4 + This release merges up the fix that appears in v2.30.9, v2.31.8, 5 + v2.32.7, v2.33.8, v2.34.8, v2.35.8, v2.36.6, v2.37.7 and v2.38.5 to 6 + address the security issues CVE-2023-25652, CVE-2023-25815, and 7 + CVE-2023-29007; see the release notes for these versions for 8 + details. 9 + 10 + This release also merges fixes that have accumulated on the 'master' 11 + front to prepare for the 2.40 release that are still relevant to 12 + 2.39.x maintenance track. 7 13 8 14 Fixes since v2.39.2 9 15 -------------------
+12 -2
apply.c
··· 4576 4576 FILE *rej; 4577 4577 char namebuf[PATH_MAX]; 4578 4578 struct fragment *frag; 4579 - int cnt = 0; 4579 + int fd, cnt = 0; 4580 4580 struct strbuf sb = STRBUF_INIT; 4581 4581 4582 4582 for (cnt = 0, frag = patch->fragments; frag; frag = frag->next) { ··· 4616 4616 memcpy(namebuf, patch->new_name, cnt); 4617 4617 memcpy(namebuf + cnt, ".rej", 5); 4618 4618 4619 - rej = fopen(namebuf, "w"); 4619 + fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666); 4620 + if (fd < 0) { 4621 + if (errno != EEXIST) 4622 + return error_errno(_("cannot open %s"), namebuf); 4623 + if (unlink(namebuf)) 4624 + return error_errno(_("cannot unlink '%s'"), namebuf); 4625 + fd = open(namebuf, O_CREAT | O_EXCL | O_WRONLY, 0666); 4626 + if (fd < 0) 4627 + return error_errno(_("cannot open %s"), namebuf); 4628 + } 4629 + rej = fdopen(fd, "w"); 4620 4630 if (!rej) 4621 4631 return error_errno(_("cannot open %s"), namebuf); 4622 4632
+25 -11
config.c
··· 3487 3487 flags); 3488 3488 } 3489 3489 3490 - static int section_name_match (const char *buf, const char *name) 3490 + static size_t section_name_match (const char *buf, const char *name) 3491 3491 { 3492 - int i = 0, j = 0, dot = 0; 3492 + size_t i = 0, j = 0; 3493 + int dot = 0; 3493 3494 if (buf[i] != '[') 3494 3495 return 0; 3495 3496 for (i = 1; buf[i] && buf[i] != ']'; i++) { ··· 3542 3543 return 1; 3543 3544 } 3544 3545 3546 + #define GIT_CONFIG_MAX_LINE_LEN (512 * 1024) 3547 + 3545 3548 /* if new_name == NULL, the section is removed instead */ 3546 3549 static int git_config_copy_or_rename_section_in_file(const char *config_filename, 3547 3550 const char *old_name, ··· 3551 3554 char *filename_buf = NULL; 3552 3555 struct lock_file lock = LOCK_INIT; 3553 3556 int out_fd; 3554 - char buf[1024]; 3557 + struct strbuf buf = STRBUF_INIT; 3555 3558 FILE *config_file = NULL; 3556 3559 struct stat st; 3557 3560 struct strbuf copystr = STRBUF_INIT; 3558 3561 struct config_store_data store; 3562 + uint32_t line_nr = 0; 3559 3563 3560 3564 memset(&store, 0, sizeof(store)); 3561 3565 ··· 3592 3596 goto out; 3593 3597 } 3594 3598 3595 - while (fgets(buf, sizeof(buf), config_file)) { 3596 - unsigned i; 3597 - int length; 3599 + while (!strbuf_getwholeline(&buf, config_file, '\n')) { 3600 + size_t i, length; 3598 3601 int is_section = 0; 3599 - char *output = buf; 3600 - for (i = 0; buf[i] && isspace(buf[i]); i++) 3602 + char *output = buf.buf; 3603 + 3604 + line_nr++; 3605 + 3606 + if (buf.len >= GIT_CONFIG_MAX_LINE_LEN) { 3607 + ret = error(_("refusing to work with overly long line " 3608 + "in '%s' on line %"PRIuMAX), 3609 + config_filename, (uintmax_t)line_nr); 3610 + goto out; 3611 + } 3612 + 3613 + for (i = 0; buf.buf[i] && isspace(buf.buf[i]); i++) 3601 3614 ; /* do nothing */ 3602 - if (buf[i] == '[') { 3615 + if (buf.buf[i] == '[') { 3603 3616 /* it's a section */ 3604 - int offset; 3617 + size_t offset; 3605 3618 is_section = 1; 3606 3619 3607 3620 /* ··· 3618 3631 strbuf_reset(&copystr); 3619 3632 } 3620 3633 3621 - offset = section_name_match(&buf[i], old_name); 3634 + offset = section_name_match(&buf.buf[i], old_name); 3622 3635 if (offset > 0) { 3623 3636 ret++; 3624 3637 if (!new_name) { ··· 3693 3706 out_no_rollback: 3694 3707 free(filename_buf); 3695 3708 config_store_data_clear(&store); 3709 + strbuf_release(&buf); 3696 3710 return ret; 3697 3711 } 3698 3712
+4
gettext.c
··· 100 100 setlocale(LC_CTYPE, "C"); 101 101 } 102 102 103 + int git_gettext_enabled = 0; 104 + 103 105 void git_setup_gettext(void) 104 106 { 105 107 const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT); ··· 118 120 setlocale(LC_TIME, ""); 119 121 init_gettext_charset("git"); 120 122 textdomain("git"); 123 + 124 + git_gettext_enabled = 1; 121 125 122 126 free(p); 123 127 }
+6
gettext.h
··· 29 29 #define FORMAT_PRESERVING(n) __attribute__((format_arg(n))) 30 30 31 31 #ifndef NO_GETTEXT 32 + extern int git_gettext_enabled; 32 33 void git_setup_gettext(void); 33 34 int gettext_width(const char *s); 34 35 #else 36 + #define git_gettext_enabled (0) 35 37 static inline void git_setup_gettext(void) 36 38 { 37 39 } ··· 45 47 { 46 48 if (!*msgid) 47 49 return ""; 50 + if (!git_gettext_enabled) 51 + return msgid; 48 52 return gettext(msgid); 49 53 } 50 54 51 55 static inline FORMAT_PRESERVING(1) FORMAT_PRESERVING(2) 52 56 const char *Q_(const char *msgid, const char *plu, unsigned long n) 53 57 { 58 + if (!git_gettext_enabled) 59 + return n == 1 ? msgid : plu; 54 60 return ngettext(msgid, plu, n); 55 61 } 56 62
+30
t/t1300-config.sh
··· 617 617 test_must_fail git config --rename-section branch.zwei "bogus name" 618 618 ' 619 619 620 + test_expect_success 'renaming a section with a long line' ' 621 + { 622 + printf "[b]\\n" && 623 + printf " c = d %1024s [a] e = f\\n" " " && 624 + printf "[a] g = h\\n" 625 + } >y && 626 + git config -f y --rename-section a xyz && 627 + test_must_fail git config -f y b.e 628 + ' 629 + 630 + test_expect_success 'renaming an embedded section with a long line' ' 631 + { 632 + printf "[b]\\n" && 633 + printf " c = d %1024s [a] [foo] e = f\\n" " " && 634 + printf "[a] g = h\\n" 635 + } >y && 636 + git config -f y --rename-section a xyz && 637 + test_must_fail git config -f y foo.e 638 + ' 639 + 640 + test_expect_success 'renaming a section with an overly-long line' ' 641 + { 642 + printf "[b]\\n" && 643 + printf " c = d %525000s e" " " && 644 + printf "[a] g = h\\n" 645 + } >y && 646 + test_must_fail git config -f y --rename-section a xyz 2>err && 647 + grep "refusing to work with overly long line in .y. on line 2" err 648 + ' 649 + 620 650 cat >> .git/config << EOF 621 651 [branch "zwei"] a = 1 [branch "vier"] 622 652 EOF
+15
t/t4115-apply-symlink.sh
··· 126 126 test_path_is_file .git/delete-me 127 127 ' 128 128 129 + test_expect_success SYMLINKS '--reject removes .rej symlink if it exists' ' 130 + test_when_finished "git reset --hard && git clean -dfx" && 131 + 132 + test_commit file && 133 + echo modified >file.t && 134 + git diff -- file.t >patch && 135 + echo modified-again >file.t && 136 + 137 + ln -s foo file.t.rej && 138 + test_must_fail git apply patch --reject 2>err && 139 + test_i18ngrep "Rejected hunk" err && 140 + test_path_is_missing foo && 141 + test_path_is_file file.t.rej 142 + ' 143 + 129 144 test_done