When setenv() is called with overwrite == 1 (eg via putenv()), the environment variable already exists and the new value is larger than the old value, a new environment object is allocated (with malloc(3)) and the current object becomes inaccessible. Repeated calls to putenv(3) updating the same environment variable with different value sizes results in objects being successively allocated without being freed. [The problem showed up because I have an application which needs to convert times across multiple timezones, which requires the `TZ' environment variable to be regularly changed] Fix: 1) Add the restriction that the actual string passed to putenv(3) will be stored in the environment (and therefore must stay in scope) - most other Unices (and The Open Group's Single Unix Specification) have this restriction. This will remove the need for putenv(3)/setenv(3) to use malloc(3) to duplicate the passed variable. 2) Keep a static bitmap of malloc'd environment strings (as against statically passed strings) within setenv(3). This would allow space for re-defined variables to be realloc'd, rather than being orphaned. Fix (1) may break FreeBSD code which relies on the FreeBSD semantics, though it shouldn't affect portable code (which presumably complies with the putenv(3) restrictions on other variants). Fix (2) is messier. How-To-Repeat: main() { while (1) { putenv("XXX=yy"); putenv("XXX=yyy"); } } compile, run and watch the process size grow :-(
>>Synopsis: memory leak in setenv(3) >... > [The problem showed up because I have an application which needs to > convert times across multiple timezones, which requires the `TZ' > environment variable to be regularly changed] I think there is already a PR by archie about this (with incomplete or wrong fixes attached). IIRC, it is impossible to fix completely, since some callers keep pointers into the environment, so the environment can't be realloc()ed. Bruce
> I think there is already a PR by archie about this (with incomplete or Yes, bin/5604. There may also be additional discussion on the -bugs list that did not get filed in the audid-trail of bin/5604.
State Changed From-To: open->closed Duplicate of PR bin/5604.