Date: Fri, 13 Jul 2007 17:15:37 -0500 (CDT) From: "Sean C. Farley" <scf@FreeBSD.org> To: Andrey Chernov <ache@nagual.pp.ru> Cc: freebsd-current <freebsd-current@FreeBSD.org> Subject: Re: Environment handling broken in /bin/sh with changes to t,set,put}env() Message-ID: <20070713152644.I26096@thor.farley.org> In-Reply-To: <20070713202433.GA19856@nagual.pp.ru> References: <20070705105922.F98700@thor.farley.org> <20070707130859.GA96605@nagual.pp.ru> <20070707131359.GB96605@nagual.pp.ru> <20070707133102.C14065@thor.farley.org> <20070707191835.GA4368@nagual.pp.ru> <20070707205410.B14065@thor.farley.org> <20070708020940.GA80166@nagual.pp.ru> <20070708171727.GA90490@nagual.pp.ru> <20070713162742.GA16260@nagual.pp.ru> <20070713142545.K26096@thor.farley.org> <20070713202433.GA19856@nagual.pp.ru>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 14 Jul 2007, Andrey Chernov wrote: > On Fri, Jul 13, 2007 at 02:39:30PM -0500, Sean C. Farley wrote: >> FreeBSD 6 will also dump if the length of the value was less than or >> equal to "/bin" since it reuses this string. This will core dump: >> >> nenv[0] = "PATH=/bin"; >> nenv[1] = NULL; >> environ = nenv; >> setenv("PATH", "/bin", 1); > > 1) I care in first hand about unsetenv() as my example states. There > nowhere said in the specs that unsetenv() may modify environ _content_, > manpage says about pointers only. Well technically, for setenv() and unsetenv() (the Open Group): If the application modifies environ or the pointers to which it points, the behavior of unsetenv() is undefined. However, I would like to have *env() functions work in this case. > 2) That example not fail under FreeBSD 6 but fail under new code: > > nenv[0] = "PATH=/bin"; > nenv[1] = NULL; > environ = nenv; > setenv("HOME", "/xxx", 1); > > (that is because new code will touch "PATH=/bin" string in anycase while > old ones looks for "HOME" only). > > The most safest way is do not touch environ content outside of > scope of requested modification. That means I agree that > nenv[0] = "PATH=/bin"; > setenv("PATH", "/bin", 1); > may fail, but not about the cases 1) and 2) Choices: 1. Call putenv() instead. The change is small, but it would create variables that are unusable to setenv() in future calls. Memory allocations could be the result. 2. Copy each string to use with setenv(). I am trying to avoid needless allocations. 3. Restructure setenv() to avoid memory allocations. I chose #3. Try the patch[1] again. It creates a setenv() function which is a wrapper around __setenv(). __setenv() takes the lengths of name and value to allow the caller to calculate the length using pointer arithmetic instead of strlen(). Sean 1. http://www.farley.org/freebsd/tmp/setenv/clearenv/patch -- scf@FreeBSD.org
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070713152644.I26096>