git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 2/2] config: clear the executable bits (if any) on $GIT_DIR/config

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Nov 16, 2014, 07:21 UTC
Message-ID
<1416122508-30654-3-git-send-email-mhagger@alum.mit.edu>
In-Reply-To
<1416122508-30654-1-git-send-email-mhagger@alum.mit.edu>

There is no reason for $GIT_DIR/config to be executable, plus there used to be a bug (fixed by the previous commit) that caused "git init" to set the u+x bit on that file. So whenever rewriting the config file, take the opportunity to remove any executable bits that the file might have.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 builtin/config.c       | 21 ++++++++++++++++++---
 config.c               | 12 ++++++++++--
 t/t1300-repo-config.sh | 13 +++++++++++++
 3 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/builtin/config.c b/builtin/config.c
index 7bba516..1a7c17e 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -551,6 +551,9 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		}
 	}
 	else if (actions == ACTION_EDIT) {
+		char *config_file;
+		struct stat st;
+
 		check_argc(argc, 0, 0);
 		if (!given_config_source.file && nongit)
 			die("not in a git directory");
@@ -559,9 +562,21 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 		if (given_config_source.blob)
 			die("editing blobs is not supported");
 		git_config(git_default_config, NULL);
-		launch_editor(given_config_source.file ?
-			      given_config_source.file : git_path("config"),
-			      NULL, NULL);
+		config_file = xstrdup(given_config_source.file ?
+				      given_config_source.file : git_path("config"));
+		launch_editor(config_file, NULL, NULL);
+
+		/*
+		 * In git 2.1, there was a bug in "git init" that left
+		 * the u+x bit set on the config file. To clean up any
+		 * repositories affected by that bug, and just because
+		 * it doesn't make sense for a config file to be
+		 * executable anyway, clear any executable bits from
+		 * the file (on a "best effort" basis):
+		 */
+		if (!lstat(config_file, &st) && (st.st_mode & 0111))
+			chmod(config_file, st.st_mode & 07666);
+		free(config_file);
 	}
 	else if (actions == ACTION_SET) {
 		int ret;
diff --git a/config.c b/config.c
index 9e42d38..47eaef4 100644
--- a/config.c
+++ b/config.c
@@ -1653,7 +1653,15 @@ int git_config_set_multivar_in_file(const char *config_filename,
 			MAP_PRIVATE, in_fd, 0);
 		close(in_fd);
 
-		if (chmod(lock->filename, st.st_mode & 07777) < 0) {
+		/*
+		 * We mask off the executable bits because (a) it
+		 * doesn't make sense to have executable bits set on
+		 * the config file, and (b) there was a bug in git 2.1
+		 * which caused the config file to be created with u+x
+		 * set, so this will help repair repositories created
+		 * with that version.
+		 */
+		if (chmod(lock->filename, st.st_mode & 07666) < 0) {
 			error("chmod on %s failed: %s",
 				lock->filename, strerror(errno));
 			ret = CONFIG_NO_WRITE;
@@ -1832,7 +1840,7 @@ int git_config_rename_section_in_file(const char *config_filename,
 
 	fstat(fileno(config_file), &st);
 
-	if (chmod(lock->filename, st.st_mode & 07777) < 0) {
+	if (chmod(lock->filename, st.st_mode & 07666) < 0) {
 		ret = error("chmod on %s failed: %s",
 				lock->filename, strerror(errno));
 		goto out;
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index 46f6ae2..7637701 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -7,6 +7,12 @@ test_description='Test git config in different settings'
 
 . ./test-lib.sh
 
+test_expect_success POSIXPERM 'any executable bits cleared' '
+	chmod u+x .git/config &&
+	git config test.me foo &&
+	test ! -x .git/config
+'
+
 test_expect_success 'clear default config' '
 	rm -f .git/config
 '
@@ -1078,6 +1084,13 @@ test_expect_success 'git config --edit respects core.editor' '
 	test_cmp expect actual
 '
 
+test_expect_success POSIXPERM 'git config --edit clears executable bits' '
+	git config -f tmp test.value no &&
+	chmod u+x tmp &&
+	GIT_EDITOR="echo [test]value=yes >" git config -f tmp --edit &&
+	test ! -x tmp
+'
+
 # malformed configuration files
 test_expect_success 'barf on syntax error' '
 	cat >.git/config <<-\EOF &&
-- 
2.1.1
Previous: Junio C HamanoNext: Johannes Sixt
Message 12 of 14 in “Don't make $GIT_DIR executable”
  1. 0/2 Don't make $GIT_DIR executableMichael Haggerty, Nov 16, 2014
  2. 1/2 create_default_files(): don't set u+x bit on $GIT_DIR/configMichael Haggerty, Nov 16, 2014
  3. Junio C HamanoNov 16, 2014
  4. Michael HaggertyNov 17, 2014
  5. Eric SunshineNov 17, 2014
  6. Torsten BögershausenNov 17, 2014
  7. Michael HaggertyNov 17, 2014
  8. Michael HaggertyNov 17, 2014
  9. Junio C HamanoNov 17, 2014
  10. Michael HaggertyNov 17, 2014
  11. Junio C HamanoNov 17, 2014
  12. 2/2 config: clear the executable bits (if any) on $GIT_DIR/configMichael Haggerty, Nov 16, 2014
  13. Johannes SixtNov 16, 2014
  14. Michael HaggertyNov 17, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.