Sync with 2.38.5
* maint-2.38: (32 commits) Git 2.38.5 Git 2.37.7 Git 2.36.6 Git 2.35.8 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 range-diff: use ssize_t for parsed "len" in read_patches() range-diff: handle unterminated lines in read_patches() range-diff: drop useless "offset" variable from read_patches() t5604: GETTEXT_POISON fix, conclusion t5604: GETTEXT_POISON fix, part 1 t5619: GETTEXT_POISON fix t0003: GETTEXT_POISON fix, conclusion ...maint
						commit
						15628975cf
					
				|  | @ -0,0 +1,43 @@ | ||||||
|  | Git v2.30.9 Release Notes | ||||||
|  | ========================= | ||||||
|  |  | ||||||
|  | This release addresses the security issues CVE-2023-25652, | ||||||
|  | CVE-2023-25815, and CVE-2023-29007. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Fixes since v2.30.8 | ||||||
|  | ------------------- | ||||||
|  |  | ||||||
|  |  * CVE-2023-25652: | ||||||
|  |  | ||||||
|  |    By feeding specially crafted input to `git apply --reject`, a | ||||||
|  |    path outside the working tree can be overwritten with partially | ||||||
|  |    controlled contents (corresponding to the rejected hunk(s) from | ||||||
|  |    the given patch). | ||||||
|  |  | ||||||
|  |  * CVE-2023-25815: | ||||||
|  |  | ||||||
|  |    When Git is compiled with runtime prefix support and runs without | ||||||
|  |    translated messages, it still used the gettext machinery to | ||||||
|  |    display messages, which subsequently potentially looked for | ||||||
|  |    translated messages in unexpected places. This allowed for | ||||||
|  |    malicious placement of crafted messages. | ||||||
|  |  | ||||||
|  |  * CVE-2023-29007: | ||||||
|  |  | ||||||
|  |    When renaming or deleting a section from a configuration file, | ||||||
|  |    certain malicious configuration values may be misinterpreted as | ||||||
|  |    the beginning of a new configuration section, leading to arbitrary | ||||||
|  |    configuration injection. | ||||||
|  |  | ||||||
|  | Credit for finding CVE-2023-25652 goes to Ry0taK, and the fix was | ||||||
|  | developed by Taylor Blau, Junio C Hamano and Johannes Schindelin, | ||||||
|  | with the help of Linus Torvalds. | ||||||
|  |  | ||||||
|  | Credit for finding CVE-2023-25815 goes to Maxime Escourbiac and | ||||||
|  | Yassine BENGANA of Michelin, and the fix was developed by Johannes | ||||||
|  | Schindelin. | ||||||
|  |  | ||||||
|  | Credit for finding CVE-2023-29007 goes to André Baptista and Vítor Pinho | ||||||
|  | of Ethiack, and the fix was developed by Taylor Blau, and Johannes | ||||||
|  | Schindelin, with help from Jeff King, and Patrick Steinhardt. | ||||||
|  | @ -0,0 +1,6 @@ | ||||||
|  | Git v2.31.8 Release Notes | ||||||
|  | ========================= | ||||||
|  |  | ||||||
|  | This release merges the fixes that appear in v2.30.9 to address the | ||||||
|  | security issues CVE-2023-25652, CVE-2023-25815, and CVE-2023-29007; | ||||||
|  | see the release notes for that version for details. | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | Git v2.32.7 Release Notes | ||||||
|  | ========================= | ||||||
|  |  | ||||||
|  | This release merges the fixes that appear in v2.30.9 and v2.31.8 to | ||||||
|  | address the security issues CVE-2023-25652, CVE-2023-25815, and | ||||||
|  | CVE-2023-29007; see the release notes for these versions for | ||||||
|  | details. | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | Git v2.33.8 Release Notes | ||||||
|  | ========================= | ||||||
|  |  | ||||||
|  | This release merges the fixes that appear in v2.30.9, v2.31.8 and | ||||||
|  | v2.32.7 to address the security issues CVE-2023-25652, | ||||||
|  | CVE-2023-25815, and CVE-2023-29007; see the release notes for these | ||||||
|  | versions for details. | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | Git v2.34.8 Release Notes | ||||||
|  | ========================= | ||||||
|  |  | ||||||
|  | This release merges the fixes that appear in v2.30.9, v2.31.8, | ||||||
|  | v2.32.7 and v2.33.8 to address the security issues CVE-2023-25652, | ||||||
|  | CVE-2023-25815, and CVE-2023-29007; see the release notes for these | ||||||
|  | versions for details. | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | Git v2.35.8 Release Notes | ||||||
|  | ========================= | ||||||
|  |  | ||||||
|  | This release merges the fixes that appear in v2.30.9, v2.31.8, | ||||||
|  | v2.32.7, v2.33.8 and v2.34.8 to address the security issues | ||||||
|  | CVE-2023-25652, CVE-2023-25815, and CVE-2023-29007; see the release | ||||||
|  | notes for these versions for details. | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | Git v2.36.6 Release Notes | ||||||
|  | ========================= | ||||||
|  |  | ||||||
|  | This release merges the fixes that appear in v2.30.9, v2.31.8, | ||||||
|  | v2.32.7, v2.33.8, v2.34.8 and v2.35.8 to address the security issues | ||||||
|  | CVE-2023-25652, CVS-2023-25815, and CVE-2023-29007; see the release | ||||||
|  | notes for these versions for details. | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | Git v2.37.7 Release Notes | ||||||
|  | ========================= | ||||||
|  |  | ||||||
|  | This release merges up the fix that appears in v2.30.9, v2.31.8, | ||||||
|  | v2.32.7, v2.33.8, v2.34.8, v2.35.8 and v2.36.6 to address the | ||||||
|  | security issues CVE-2023-25652, CVE-2023-25815, and CVE-2023-29007; | ||||||
|  | see the release notes for these versions for details. | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | Git v2.38.5 Release Notes | ||||||
|  | ========================= | ||||||
|  |  | ||||||
|  | This release merges up the fix that appears in v2.30.9, v2.31.8, | ||||||
|  | v2.32.7, v2.33.8, v2.34.8, v2.35.8, v2.36.6 and v2.37.7 to address | ||||||
|  | the security issues CVE-2023-25652, CVE-2023-25815, and | ||||||
|  | CVE-2023-29007; see the release notes for these versions for | ||||||
|  | details. | ||||||
							
								
								
									
										14
									
								
								apply.c
								
								
								
								
							
							
						
						
									
										14
									
								
								apply.c
								
								
								
								
							|  | @ -4576,7 +4576,7 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch) | ||||||
| 	FILE *rej; | 	FILE *rej; | ||||||
| 	char namebuf[PATH_MAX]; | 	char namebuf[PATH_MAX]; | ||||||
| 	struct fragment *frag; | 	struct fragment *frag; | ||||||
| 	int cnt = 0; | 	int fd, cnt = 0; | ||||||
| 	struct strbuf sb = STRBUF_INIT; | 	struct strbuf sb = STRBUF_INIT; | ||||||
|  |  | ||||||
| 	for (cnt = 0, frag = patch->fragments; frag; frag = frag->next) { | 	for (cnt = 0, frag = patch->fragments; frag; frag = frag->next) { | ||||||
|  | @ -4616,7 +4616,17 @@ static int write_out_one_reject(struct apply_state *state, struct patch *patch) | ||||||
| 	memcpy(namebuf, patch->new_name, cnt); | 	memcpy(namebuf, patch->new_name, cnt); | ||||||
| 	memcpy(namebuf + cnt, ".rej", 5); | 	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) | 	if (!rej) | ||||||
| 		return error_errno(_("cannot open %s"), namebuf); | 		return error_errno(_("cannot open %s"), namebuf); | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										36
									
								
								config.c
								
								
								
								
							
							
						
						
									
										36
									
								
								config.c
								
								
								
								
							|  | @ -3487,9 +3487,10 @@ void git_config_set_multivar(const char *key, const char *value, | ||||||
| 					flags); | 					flags); | ||||||
| } | } | ||||||
|  |  | ||||||
| static int section_name_match (const char *buf, const char *name) | static size_t section_name_match (const char *buf, const char *name) | ||||||
| { | { | ||||||
| 	int i = 0, j = 0, dot = 0; | 	size_t i = 0, j = 0; | ||||||
|  | 	int dot = 0; | ||||||
| 	if (buf[i] != '[') | 	if (buf[i] != '[') | ||||||
| 		return 0; | 		return 0; | ||||||
| 	for (i = 1; buf[i] && buf[i] != ']'; i++) { | 	for (i = 1; buf[i] && buf[i] != ']'; i++) { | ||||||
|  | @ -3542,6 +3543,8 @@ static int section_name_is_ok(const char *name) | ||||||
| 	return 1; | 	return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #define GIT_CONFIG_MAX_LINE_LEN (512 * 1024) | ||||||
|  |  | ||||||
| /* if new_name == NULL, the section is removed instead */ | /* if new_name == NULL, the section is removed instead */ | ||||||
| static int git_config_copy_or_rename_section_in_file(const char *config_filename, | static int git_config_copy_or_rename_section_in_file(const char *config_filename, | ||||||
| 				      const char *old_name, | 				      const char *old_name, | ||||||
|  | @ -3551,11 +3554,12 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename | ||||||
| 	char *filename_buf = NULL; | 	char *filename_buf = NULL; | ||||||
| 	struct lock_file lock = LOCK_INIT; | 	struct lock_file lock = LOCK_INIT; | ||||||
| 	int out_fd; | 	int out_fd; | ||||||
| 	char buf[1024]; | 	struct strbuf buf = STRBUF_INIT; | ||||||
| 	FILE *config_file = NULL; | 	FILE *config_file = NULL; | ||||||
| 	struct stat st; | 	struct stat st; | ||||||
| 	struct strbuf copystr = STRBUF_INIT; | 	struct strbuf copystr = STRBUF_INIT; | ||||||
| 	struct config_store_data store; | 	struct config_store_data store; | ||||||
|  | 	uint32_t line_nr = 0; | ||||||
|  |  | ||||||
| 	memset(&store, 0, sizeof(store)); | 	memset(&store, 0, sizeof(store)); | ||||||
|  |  | ||||||
|  | @ -3592,16 +3596,25 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename | ||||||
| 		goto out; | 		goto out; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	while (fgets(buf, sizeof(buf), config_file)) { | 	while (!strbuf_getwholeline(&buf, config_file, '\n')) { | ||||||
| 		unsigned i; | 		size_t i, length; | ||||||
| 		int length; |  | ||||||
| 		int is_section = 0; | 		int is_section = 0; | ||||||
| 		char *output = buf; | 		char *output = buf.buf; | ||||||
| 		for (i = 0; buf[i] && isspace(buf[i]); i++) |  | ||||||
|  | 		line_nr++; | ||||||
|  |  | ||||||
|  | 		if (buf.len >= GIT_CONFIG_MAX_LINE_LEN) { | ||||||
|  | 			ret = error(_("refusing to work with overly long line " | ||||||
|  | 				      "in '%s' on line %"PRIuMAX), | ||||||
|  | 				    config_filename, (uintmax_t)line_nr); | ||||||
|  | 			goto out; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		for (i = 0; buf.buf[i] && isspace(buf.buf[i]); i++) | ||||||
| 			; /* do nothing */ | 			; /* do nothing */ | ||||||
| 		if (buf[i] == '[') { | 		if (buf.buf[i] == '[') { | ||||||
| 			/* it's a section */ | 			/* it's a section */ | ||||||
| 			int offset; | 			size_t offset; | ||||||
| 			is_section = 1; | 			is_section = 1; | ||||||
|  |  | ||||||
| 			/* | 			/* | ||||||
|  | @ -3618,7 +3631,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename | ||||||
| 				strbuf_reset(©str); | 				strbuf_reset(©str); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			offset = section_name_match(&buf[i], old_name); | 			offset = section_name_match(&buf.buf[i], old_name); | ||||||
| 			if (offset > 0) { | 			if (offset > 0) { | ||||||
| 				ret++; | 				ret++; | ||||||
| 				if (!new_name) { | 				if (!new_name) { | ||||||
|  | @ -3693,6 +3706,7 @@ out: | ||||||
| out_no_rollback: | out_no_rollback: | ||||||
| 	free(filename_buf); | 	free(filename_buf); | ||||||
| 	config_store_data_clear(&store); | 	config_store_data_clear(&store); | ||||||
|  | 	strbuf_release(&buf); | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -100,6 +100,8 @@ static void init_gettext_charset(const char *domain) | ||||||
| 		setlocale(LC_CTYPE, "C"); | 		setlocale(LC_CTYPE, "C"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | int git_gettext_enabled = 0; | ||||||
|  |  | ||||||
| void git_setup_gettext(void) | void git_setup_gettext(void) | ||||||
| { | { | ||||||
| 	const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT); | 	const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT); | ||||||
|  | @ -119,6 +121,8 @@ void git_setup_gettext(void) | ||||||
| 	init_gettext_charset("git"); | 	init_gettext_charset("git"); | ||||||
| 	textdomain("git"); | 	textdomain("git"); | ||||||
|  |  | ||||||
|  | 	git_gettext_enabled = 1; | ||||||
|  |  | ||||||
| 	free(p); | 	free(p); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -29,9 +29,11 @@ | ||||||
| #define FORMAT_PRESERVING(n) __attribute__((format_arg(n))) | #define FORMAT_PRESERVING(n) __attribute__((format_arg(n))) | ||||||
|  |  | ||||||
| #ifndef NO_GETTEXT | #ifndef NO_GETTEXT | ||||||
|  | extern int git_gettext_enabled; | ||||||
| void git_setup_gettext(void); | void git_setup_gettext(void); | ||||||
| int gettext_width(const char *s); | int gettext_width(const char *s); | ||||||
| #else | #else | ||||||
|  | #define git_gettext_enabled (0) | ||||||
| static inline void git_setup_gettext(void) | static inline void git_setup_gettext(void) | ||||||
| { | { | ||||||
| } | } | ||||||
|  | @ -45,12 +47,16 @@ static inline FORMAT_PRESERVING(1) const char *_(const char *msgid) | ||||||
| { | { | ||||||
| 	if (!*msgid) | 	if (!*msgid) | ||||||
| 		return ""; | 		return ""; | ||||||
|  | 	if (!git_gettext_enabled) | ||||||
|  | 		return msgid; | ||||||
| 	return gettext(msgid); | 	return gettext(msgid); | ||||||
| } | } | ||||||
|  |  | ||||||
| static inline FORMAT_PRESERVING(1) FORMAT_PRESERVING(2) | static inline FORMAT_PRESERVING(1) FORMAT_PRESERVING(2) | ||||||
| const char *Q_(const char *msgid, const char *plu, unsigned long n) | const char *Q_(const char *msgid, const char *plu, unsigned long n) | ||||||
| { | { | ||||||
|  | 	if (!git_gettext_enabled) | ||||||
|  | 		return n == 1 ? msgid : plu; | ||||||
| 	return ngettext(msgid, plu, n); | 	return ngettext(msgid, plu, n); | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -617,6 +617,36 @@ test_expect_success 'renaming to bogus section is rejected' ' | ||||||
| 	test_must_fail git config --rename-section branch.zwei "bogus name" | 	test_must_fail git config --rename-section branch.zwei "bogus name" | ||||||
| ' | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'renaming a section with a long line' ' | ||||||
|  | 	{ | ||||||
|  | 		printf "[b]\\n" && | ||||||
|  | 		printf "  c = d %1024s [a] e = f\\n" " " && | ||||||
|  | 		printf "[a] g = h\\n" | ||||||
|  | 	} >y && | ||||||
|  | 	git config -f y --rename-section a xyz && | ||||||
|  | 	test_must_fail git config -f y b.e | ||||||
|  | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'renaming an embedded section with a long line' ' | ||||||
|  | 	{ | ||||||
|  | 		printf "[b]\\n" && | ||||||
|  | 		printf "  c = d %1024s [a] [foo] e = f\\n" " " && | ||||||
|  | 		printf "[a] g = h\\n" | ||||||
|  | 	} >y && | ||||||
|  | 	git config -f y --rename-section a xyz && | ||||||
|  | 	test_must_fail git config -f y foo.e | ||||||
|  | ' | ||||||
|  |  | ||||||
|  | test_expect_success 'renaming a section with an overly-long line' ' | ||||||
|  | 	{ | ||||||
|  | 		printf "[b]\\n" && | ||||||
|  | 		printf "  c = d %525000s e" " " && | ||||||
|  | 		printf "[a] g = h\\n" | ||||||
|  | 	} >y && | ||||||
|  | 	test_must_fail git config -f y --rename-section a xyz 2>err && | ||||||
|  | 	grep "refusing to work with overly long line in .y. on line 2" err | ||||||
|  | ' | ||||||
|  |  | ||||||
| cat >> .git/config << EOF | cat >> .git/config << EOF | ||||||
|   [branch "zwei"] a = 1 [branch "vier"] |   [branch "zwei"] a = 1 [branch "vier"] | ||||||
| EOF | EOF | ||||||
|  |  | ||||||
|  | @ -126,4 +126,19 @@ test_expect_success SYMLINKS 'symlink escape when deleting file' ' | ||||||
| 	test_path_is_file .git/delete-me | 	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 | test_done | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Johannes Schindelin
						Johannes Schindelin