[Toybox] setenv memory leak.

2019-04-08 Thread Rob Landley
I'm inching towards reopening the toysh can of worms, and last time I opened it
there was a problem with environment variable memory leaking in libc:

  https://landley.net/notes-2006.html#24-10-2006

Over the years I griped about this to Rich Felker, who fixed it in musl:

  http://git.musl-libc.org/cgit/musl/tree/src/env/setenv.c

But bionic still leaks each entry when you replace it:


https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/upstream-openbsd/lib/libc/stdlib/setenv.c

Meaning if you do:

  for (i = 0; i<9; i++) setenv("this", "that", 1);

It'll leak 9 gigabytes.

This seems suboptimal, and is bad for long-running shell scripts.

I'm also trying to redo the tar "command mode" (does anyone _use_ this? It was
submitted so I _assume_ so but I've never encountered it in the wild) to use
nommu-friendly xpopen_both() and the _easy_ way is to just set the environment
variables in the host before the vfork() but that's resetting the same variables
an aribtrary number of times and if libc can't free the variable memory...

Rob

P.S. I can do it myself with putenv() or my own direct environ() manipulation
but that's not my first choice? Nor is rewriting xpopen() to have a callback
doing arbitrary stuff in the vfork context before it execs, kinda defeats the
point of that function...

P.P.S. I honestly don't care if glibc gets this right or I'd have poked them
about it sometime over the past 15 years. If they can't gnu/do the basic "wait,
how does this work and what happens if" stuff a civilian like me does in passing
that's _their_ gnu/problem.
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] setenv memory leak.

2019-04-08 Thread Rob Landley
On 4/8/19 1:42 PM, Rob Landley wrote:
> I'm inching towards reopening the toysh can of worms, and last time I opened 
> it
> there was a problem with environment variable memory leaking in libc:
> 
>   https://landley.net/notes-2006.html#24-10-2006

Nevermind, creating a lib/env.c to do this stuff properly, with the usual
xsetenv() and friends.

This isn't hard, and I'm not gonna guess what libc du jour gets right...

(The design I had way back when, with an initial envc count that decrements
every time we drop something out of our initial environment, and everything else
is our allocation we can free again, seems quite reasonable. I should leave
/proc/self/environment alone the same way I leave /proc/self/cmdline alone, it's
what we inherited at exec() time not what we're using now.)

Rob
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] setenv memory leak.

2019-04-08 Thread enh via Toybox
why does toysh care? shells i've seen don't call setenv at all ---
they maintain an "environ" of their own for their children.

On Mon, Apr 8, 2019 at 11:42 AM Rob Landley  wrote:
>
> I'm inching towards reopening the toysh can of worms, and last time I opened 
> it
> there was a problem with environment variable memory leaking in libc:
>
>   https://landley.net/notes-2006.html#24-10-2006
>
> Over the years I griped about this to Rich Felker, who fixed it in musl:
>
>   http://git.musl-libc.org/cgit/musl/tree/src/env/setenv.c
>
> But bionic still leaks each entry when you replace it:
>
>
> https://android.googlesource.com/platform/bionic/+/refs/heads/master/libc/upstream-openbsd/lib/libc/stdlib/setenv.c
>
> Meaning if you do:
>
>   for (i = 0; i<9; i++) setenv("this", "that", 1);
>
> It'll leak 9 gigabytes.
>
> This seems suboptimal, and is bad for long-running shell scripts.
>
> I'm also trying to redo the tar "command mode" (does anyone _use_ this? It was
> submitted so I _assume_ so but I've never encountered it in the wild) to use
> nommu-friendly xpopen_both() and the _easy_ way is to just set the environment
> variables in the host before the vfork() but that's resetting the same 
> variables
> an aribtrary number of times and if libc can't free the variable memory...
>
> Rob
>
> P.S. I can do it myself with putenv() or my own direct environ() manipulation
> but that's not my first choice? Nor is rewriting xpopen() to have a callback
> doing arbitrary stuff in the vfork context before it execs, kinda defeats the
> point of that function...
>
> P.P.S. I honestly don't care if glibc gets this right or I'd have poked them
> about it sometime over the past 15 years. If they can't gnu/do the basic 
> "wait,
> how does this work and what happens if" stuff a civilian like me does in 
> passing
> that's _their_ gnu/problem.
> ___
> Toybox mailing list
> Toybox@lists.landley.net
> http://lists.landley.net/listinfo.cgi/toybox-landley.net
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] setenv memory leak.

2019-04-08 Thread Rob Landley
On 4/8/19 2:31 PM, enh wrote:
> why does toysh care? shells i've seen don't call setenv at all ---
> they maintain an "environ" of their own for their children.

Yes, they have to do it themselves because libc is doing it unusably wrong for
anything that persists and changes environment variables repeatedly.

*shrug* Reinventing this wheel isn't hard, I'd just hoped I wouldn't have to.
But I didn't complain widely enough long ago, and only musl fixed the leak.

Rob

P.S. I tried to make ftw() work before writing dirtree, I tried to make
realpath() work before writing xrealpath(), I tried pretty hard to avoid writing
next_printf() at all...
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net


Re: [Toybox] setenv memory leak.

2019-04-08 Thread Josh Gao via Toybox
On Mon, Apr 8, 2019 at 1:12 PM Rob Landley  wrote:
> Yes, they have to do it themselves because libc is doing it unusably wrong for
> anything that persists and changes environment variables repeatedly.
>
> *shrug* Reinventing this wheel isn't hard, I'd just hoped I wouldn't have to.
> But I didn't complain widely enough long ago, and only musl fixed the leak.

Shells need to keep track of variables separately from the environment to
handle non-exported variables anyway. I suppose you could keep everything
in the environment and keep a list of non-exported variables as well, but
that just seems like more work for no reason.

Making setenv not leak seems impossible in the presence of threaded code,
anyway: you have no way of knowing whether the return value of getenv just got
freed because some other thread came in and called setenv, so the only solution
is basically to just never call setenv (but that fixes your leak, too!).
___
Toybox mailing list
Toybox@lists.landley.net
http://lists.landley.net/listinfo.cgi/toybox-landley.net