Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001598 [1003.1(2016/18)/Issue7+TC2] System Interfaces Editorial Enhancement Request 2022-08-06 17:37 2022-11-08 14:09
Reporter alanc View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Applied  
Name Alan Coopersmith
Organization Oracle Solaris
User Reference
Section putenv
Page Number (page or range of pages)
Line Number (Line or range of lines)
Interp Status ---
Final Accepted Text Note: 0006013
Summary 0001598: putenv should be allowed to fail with EINVAL
Description setenv() is required to fail and return EINVAL if "The envname argument points
to an empty string or points to a string containing an '=' character." in
order to keep the environment in the expected "name=value" format.

putenv() currently states 'The string argument should point to a string of the form " name= value ".' but does not state what happens if that is not true.

Some implementations currently accept invalid values while others check and
reject them.

GNU libc has added an extension to accept strings without an '=' character as
an alias to unsetenv(), but does not seem to check for empty strings or
otherwise generate EINVAL errors:
   https://man7.org/linux/man-pages/man3/putenv.3.html [^]
   https://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/putenv.c [^]

musl libc does the same as GNU libc:
   https://git.musl-libc.org/cgit/musl/tree/src/env/putenv.c?h=v1.2.3 [^]

OpenBSD returns -1 and sets errno to EINVAL if the string does not contain
an '=' character:
   https://man.openbsd.org/putenv.3 [^]
   https://github.com/openbsd/src/blob/master/lib/libc/stdlib/setenv.c [^]

FreeBSD is similar to OpenBSD but also generates EINVAL if the string is NULL,
or the '=' is the first character of the string:
   https://www.freebsd.org/cgi/man.cgi?query=putenv&sektion=3&format=html [^]
   https://cgit.freebsd.org/src/tree/lib/libc/stdlib/getenv.c?h=release/13.1.0#n614 [^]

NetBSD performs the same checks as FreeBSD:
   https://man.netbsd.org/putenv.3 [^]
   https://github.com/NetBSD/src/blob/trunk/lib/libc/stdlib/putenv.c#L59-L63 [^]
   https://github.com/NetBSD/src/blob/trunk/lib/libc/stdlib/_env.c#L123-L148 [^]

illumos only checks for the string containing an '=', and if not, follows
GNU libc in passing it to unsetenv() and does not ever generate EINVAL:
   https://github.com/illumos/illumos-gate/blob/master/usr/src/lib/libc/port/gen/getenv.c#L337-L351 [^]
   https://illumos.org/man/3C/putenv [^]

Solaris prior to Solaris 11.4.27 performed no checks on the string and would
never generate EINVAL:
   https://docs.oracle.com/cd/E86824_01/html/E54766/putenv-3c.html [^]
This has changed in Solaris 11.4.27 and later, in which Solaris will return
-1 and set errno to EINVAL if the string is empty or starts with '=', and
pass the string to unsetenv() if the string has a variable name but no '='.
(The man page changes documenting this are in process and not yet published.)
Desired Action Add to the 'The putenv() function may fail if:' list in the ERRORS section:

[EINVAL]
    The string argument is not a pointer to a string of the form "name=value".

Listing this as "may" fail instead of "must" fail maintains compatibility with
all of the implementations discussed above, including those with the extension
to unsetenv a name provided with no '=value'.
Tags tc3-2008
Attached Files

- Relationships

-  Notes
(0005926)
geoffclare (manager)
2022-08-08 09:02

The EINVAL error is already allowed courtesy of the general rules for additional errors (XSH 2.3). However, adding it is worth doing so that implementations can't choose a different error value instead of EINVAL for this condition. (Although the suggested wording is not quite right as it also covers, for example, a null pointer.)

More importantly, just adding the EINVAL error is not sufficient to allow the new Solaris behaviour (and Illumos, glibc and muslc). The first sentence of the putenv() description is `The putenv() function shall use the string argument to set environment variable values.' Notice the word set. This would not be a problem if it later said `The application shall ensure that the string argument points to a string of the form "name=value"', as the absence of an "=" would then be undefined behaviour, but because it only says `should', putenv() is required only to set, never unset, environment variables if it succeeds.

To allow putenv("name") to remove "name" from the environment, a more extensive rewording will be needed. I think it should explicitly only allow two behaviours (removing "name" or failing with EINVAL).
(0006013)
geoffclare (manager)
2022-10-25 10:56

Suggested changes...

On page 1751 line 56642 section putenv(), change:
The putenv() function shall use the string argument to set environment variable values. The string argument should point to a string of the form "name=value". The putenv() function shall make the value of the environment variable name equal to value by altering an existing variable or creating a new one. In either case, the string pointed to by string shall become part of the environment, so altering the string shall change the environment.
to:
The putenv() function shall use the string argument to set, or optionally unset, an environment variable value:

  • If the string argument points to a string of the form "name=value", where name is a valid name, the putenv() function shall make the value of the environment variable with that name equal to value by altering an existing variable or creating a new one. In either case, the string pointed to by string shall become part of the environment, so altering the string shall change the environment.

  • If the string argument points to a string containing a valid name, the putenv() function shall either remove the environment variable with that name (if it exists) from the environment or fail with errno set to [EINVAL].

  • Otherwise, the behavior is unspecified.

After page 1751 line 56652 section putenv(), add:
[EINVAL]
The string argument points to a string that is not of the form "name=value", where name is a valid name.

- Issue History
Date Modified Username Field Change
2022-08-06 17:37 alanc New Issue
2022-08-06 17:37 alanc Name => Alan Coopersmith
2022-08-06 17:37 alanc Organization => Oracle Solaris
2022-08-06 17:37 alanc Section => putenv
2022-08-06 17:37 alanc Page Number => (page or range of pages)
2022-08-06 17:37 alanc Line Number => (Line or range of lines)
2022-08-08 09:02 geoffclare Note Added: 0005926
2022-08-08 09:04 geoffclare Project 1003.1(2013)/Issue7+TC1 => 1003.1(2016/18)/Issue7+TC2
2022-10-25 10:56 geoffclare Note Added: 0006013
2022-10-27 15:24 geoffclare Interp Status => ---
2022-10-27 15:24 geoffclare Final Accepted Text => Note: 0006013
2022-10-27 15:24 geoffclare Status New => Resolved
2022-10-27 15:24 geoffclare Resolution Open => Accepted As Marked
2022-10-27 15:24 geoffclare Tag Attached: tc3-2008
2022-11-08 14:09 geoffclare Status Resolved => Applied


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker