[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Environment handling broken in /bin/sh with changes to t,set,put}env()



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_(_at_)_FreeBSD_(_dot_)_org
_______________________________________________
freebsd-current_(_at_)_freebsd_(_dot_)_org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscribe_(_at_)_freebsd_(_dot_)_org"


Visit your host, monkey.org