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

[PATCH, maint] setup: make sure git_dir path is in a permanent buffer, getenv(3) case

From
Kirill Smelkov <kirr@mns.spb.ru>
Date
Nov 11, 2010, 18:08 UTC
Message-ID
<1289498903-18413-1-git-send-email-kirr@mns.spb.ru>

getenv(3) returns not-permanent buffer which may be changed by e.g. putenv(3) call (*).

In practice I've noticed this when trying to do `git commit -m abc` inside msysgit under wine, getting

    $ git commit -m abc
    fatal: could not open 'DIR=.git/COMMIT_EDITMSG': No such file or directory
                           ^^^^
    (notice introduced 'DIR=' artifact.)

The problem was showing itself only with -m option, and actually, as debugging showed, originally

    git_dir = getenv("GIT_DIR")
returned pointer to
        "GIT_DIR=.git\0"
                 ^
               git_dir

, we stored it in git_dir, than, after processing -m git-commit option, we did setenv("GIT_EDITOR", ":") which as (*) says changed environment variables memory layout - something like this

       "...\0GIT_DIR=.git\0"
                 ^
               git_dir
and oops - we got wrong git_dir.

Avoid that by strdupping getenv("GIT_DIR") result like we did in 06f354 (setup: make sure git dir path is in a permanent buffer). Unfortunately this also shows that other getenv usage inside git needs auditing...

(*) from man 3 getenv:
       The implementation of getenv() is not required to  be  reentrant.   The
       string  pointed  to  by  the return value of getenv() may be statically
       allocated, and can be  modified  by  a  subsequent  call  to  getenv(),
       putenv(3), setenv(3), or unsetenv(3).
Cc: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru>
---
 environment.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/environment.c b/environment.c
index eaf908b..d5021e8 100644
--- a/environment.c
+++ b/environment.c
@@ -88,6 +88,7 @@ const char * const local_repo_env[LOCAL_REPO_ENV_SIZE + 1] = {
 static void setup_git_env(void)
 {
 	git_dir = getenv(GIT_DIR_ENVIRONMENT);
+	git_dir = git_dir ? xstrdup(git_dir) : NULL;
 	if (!git_dir) {
 		git_dir = read_gitfile_gently(DEFAULT_GIT_DIR_ENVIRONMENT);
 		git_dir = git_dir ? xstrdup(git_dir) : NULL;
-- 
1.7.3.2.161.g3089c
Next: Jonathan Nieder
Message 1 of 6 in “setup: make sure git_dir path is in a permanent buffer, getenv(3) case”
  1. setup: make sure git_dir path is in a permanent buffer, getenv(3) caseKirill Smelkov, Nov 11, 2010
  2. Jonathan NiederNov 11, 2010
  3. Kirill SmelkovNov 12, 2010
  4. Jonathan NiederNov 12, 2010
  5. Kirill SmelkovNov 12, 2010
  6. tests: add GETENV_POISON option to simulate unfriendly getenv()Jonathan Nieder, Nov 12, 2010

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.