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

Re: [PATCH v2 4/4] use wrapper for unchecked setenv/putenv calls

From
Erik Faye-Lund <kusmabite@gmail.com>
Date
Dec 15, 2011, 18:04 UTC
Message-ID
<CABPQNSY+Q=Dt8oKodJMqRRb+ADdfDgQTxWKDfOpHvb5L9J=vvw@mail.gmail.com>
In-Reply-To
<20111214181658.GA1691@sigill.intra.peff.net>
On Wed, Dec 14, 2011 at 7:16 PM, Jeff King <peff@peff.net> wrote:
Show 19 quoted lines
> On Wed, Dec 14, 2011 at 03:07:11PM +0100, Erik Faye-Lund wrote:
>
>> This avoids us from accidentally dropping state, possibly leading
>> to unexpected behaviour.
>
> I do think this is fine in a "be extra cautious" kind of way.
>
>> This is especially important on Windows, where the maximum size of
>> the environment is 32 kB.
>
> But does your patch actually detect that? As Andreas pointed out, these
> limits don't typically come into play at setenv time. Instead, the
> environment is allocated on the heap, and then the result is passed to
> exec/spawn, which will fail.
>
> So your patch is really detecting a failure to malloc, not an overflow
> of the environment size, and Windows is just as (un)likely to run out of
> heap as any other platform.
>

You are right; I just assumed that our setenv was implemented on top of SetEnvironmentVariable, which does impose max-limits on setting (if I read the documentation correctly): http://msdn.microsoft.com/en-us/library/windows/desktop/ms686206(v=vs.85).aspx

But we don't. We have mingw_setenv, which simply modifies environ.
Show 34 quoted lines
> You can check how your platform behaves by applying this patch:
>
> diff --git a/git.c b/git.c
> index f10e434..57f6b12 100644
> --- a/git.c
> +++ b/git.c
> @@ -223,6 +223,16 @@ static int handle_alias(int *argcp, const char ***argv)
>                                alias_argv[i] = (*argv)[i];
>                        alias_argv[argc] = NULL;
>
> +                       /* make gigantic environment */
> +                       {
> +                               int len = 256 * 1024;
> +                               char *buf = xmalloc(len);
> +                               memset(buf, 'z', len);
> +                               buf[len-1] = '\0';
> +                               if (setenv("FOO", buf, 1))
> +                                       die("setenv failed");
> +                       }
> +
>                        ret = run_command_v_opt(alias_argv, RUN_USING_SHELL);
>                        if (ret >= 0)   /* normal exit */
>                                exit(ret);
>
> and then running:
>
>  git -c alias.foo='!echo ok' foo
>
> which yields:
>
>  fatal: cannot exec 'echo ok': Argument list too long
>
> on Linux.
>

Yeah, but I'm getting: $ git -c alias.foo='!echo ok' foo ok

Which is strange to me.

But if I do: $ git -c alias.foo='!echo $FOO' foo

it does echo a bunch of 'z's. And we get the expected amount:
$ git -c alias.foo='!echo $FOO' foo | wc -c
 262144

This strikes me as very strange, because we end up calling the ANSI version of CreateProcess with an environment-block beyond 32767 chars, which MSDN says should fail:

"The ANSI version of this function, CreateProcessA fails if the total size of the environment block for the process exceeds 32,767 characters."

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
Oh well, this is strange behavior in a good way; I'm not going to complain :P
Previous: Jeff King
Message 9 of 9 in “setenv/putenv errors”
  1. 0/4 setenv/putenv errorsErik Faye-Lund, Dec 14, 2011
  2. 1/4 compat/setenv.c: update errno when erroring outErik Faye-Lund, Dec 14, 2011
  3. 2/4 compat/setenv.c: error if name contains '='Erik Faye-Lund, Dec 14, 2011
  4. 3/4 wrapper: supply xsetenv and xputenvErik Faye-Lund, Dec 14, 2011
  5. Junio C HamanoDec 15, 2011
  6. Erik Faye-LundDec 15, 2011
  7. 4/4 use wrapper for unchecked setenv/putenv callsErik Faye-Lund, Dec 14, 2011
  8. Jeff KingDec 14, 2011
  9. Erik Faye-LundDec 15, 2011

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.