Bug 18256
Summary: | putenv declared as putenv(char*) and not as putenv(const char*) | ||
---|---|---|---|
Product: | [Retired] Red Hat Linux | Reporter: | peter.stamfest |
Component: | glibc | Assignee: | Jakub Jelinek <jakub> |
Status: | CLOSED NOTABUG | QA Contact: | |
Severity: | medium | Docs Contact: | |
Priority: | medium | ||
Version: | 7.0 | CC: | dr |
Target Milestone: | --- | ||
Target Release: | --- | ||
Hardware: | i686 | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2000-10-03 19:11:22 UTC | Type: | --- |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: |
Description
peter.stamfest
2000-10-03 19:05:41 UTC
putenv is intentionally declared with char *, not const char *, because unlike setenv, it puts that string directly into environment, meaning anyone changing environment can change your string passed to putenv. That's e.g. why UNIX98 declares putenv char * as well, and AFAIK all glibcs did it that way. If you have a buggy program which passes a constant string to putenv, you should fix it or cast it to (char *) if you can ensure noone will temper with it. I do understand what you mean So why do both the man page and the info files always refer to putenv(const char*)? Should that have been a problem all the time? It definitely IS a change.WRT earlier libcs. On my RH6 system I have (glibc-2.1.2-11): extern int putenv __P ((__const char *__string)); in /usr/include/stdlib.h Interestingly enough, ENOMEM is listed as possible error code for putenv in my glibc-2.1.2-11, something that indicates that there is some allocation going on. Users might guess from this information that a copy of their string is made implicitely. So there is a documentation problem somewhere. And a lot of "buggy" code. Well, if you look at info libc in 7.0, you'll see putenv(char *). If you look at putenv(3) manpage, the prototype is written there as putenv(const char *), yes, but if you read on, you'll see that: The libc4 and libc5 and glibc 2.1.2 versions conform to SUSv2: the pointer string given to putenv() is used. In particular, this string becomes part of the environment; changing it later will change the environment. (Thus, it is an error is to call putenv() with an automatic variable as the argument, then return from the calling function while string is still part of the environment.) However, glibc 2.0-2.1.1 differs: a copy of the string is used. On the one hand this causes a memory leak, and on the other hand it violates SUSv2. This has been fixed in glibc2.1.2. and SUSv2 removes the `const' from the prototype, and so does glibc 2.1.3. If you check RHL 6.2, putenv already has (char *) prototype, so this is nothing new in glibc 2.1.9x. |