setenv ("NAME", NULL) corrupts environment

Bug #861132 reported by Robert Ancell
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
eglibc
Invalid
Medium
eglibc (Ubuntu)
New
Undecided
Unassigned

Bug Description

setenv ("NAME", NULL) corrupts the environment. It doesn't seem specified what the function should do when value is NULL, but the code does check for it - it just does the wrong thing:

stdlib/setenv.c:
...
__add_to_environ (name, value, combined, replace)
...
  const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
...
      memcpy (new_value, name, namelen);
      new_value[namelen] = '=';
      memcpy (&new_value[namelen + 1], value, vallen);
...

i.e. the new value is set to "NAME=" without the trailing nul character.

Found in bug 861123 where indicator-datetime does a:
x = g_strdup (getenv ("NAME"));
unsetenv ("NAME");
// do something
setenv ("NAME", x);

Tags: patch
Revision history for this message
Robert Ancell (robert-ancell) wrote :
Revision history for this message
In , Robert Ancell (robert-ancell) wrote :

Created attachment 5948
Proposed patch, which treats NULL value as "" (which I think is what the current code intends).

setenv ("NAME", NULL) corrupts the environment. It doesn't seem specified what the function should do when value is NULL, but the code does check for it - it just does the wrong thing:

stdlib/setenv.c:
...
__add_to_environ (name, value, combined, replace)
...
  const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
...
      memcpy (new_value, name, namelen);
      new_value[namelen] = '=';
      memcpy (&new_value[namelen + 1], value, vallen);
...

i.e. the new value is set to "NAME=" without the trailing nul character.

Changed in eglibc:
importance: Unknown → Medium
status: Unknown → Confirmed
Revision history for this message
Ubuntu Foundations Team Bug Bot (crichton) wrote :

The attachment "Proposed fix" of this bug report has been identified as being a patch. The ubuntu-reviewers team has been subscribed to the bug report so that they can review the patch. In the event that this is in fact not a patch you can resolve this situation by removing the tag 'patch' from the bug report and editing the attachment so that it is not flagged as a patch. Additionally, if you are member of the ubuntu-sponsors please also unsubscribe the team from this bug report.

[This is an automated message performed by a Launchpad user owned by Brian Murray. Please contact him regarding any issues with the action taken in this bug report.]

tags: added: patch
Revision history for this message
In , Drepper-fsp (drepper-fsp) wrote :

The parameter is supposed to be a string pointer. NULL is no string pointer, neither is in most case -1 etc. There is no way to catch invalid pointers and any such effort would only hurt correct code. Just fix your code.

Changed in eglibc:
status: Confirmed → Invalid
Revision history for this message
In , Robert Ancell (robert-ancell) wrote :

Could you please consider changing this line then:
  const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
to:
  const size_t vallen = strlen (value) + 1;

This is detecting that value is NULL, handling it, then causing a greater problem later on in the function. If value must be non NULL then a segmentation fault is preferable to a memory corruption which is much harded to diagnose.

Revision history for this message
In , Drepper-fsp (drepper-fsp) wrote :

(In reply to comment #2)
> Could you please consider changing this line then:

No, this would require unnecessary other changes.

Revision history for this message
In , Dmitry V. Levin (ldv) wrote :

(In reply to comment #3)
> (In reply to comment #2)
> > Could you please consider changing this line then:
>
> No, this would require unnecessary other changes.

Since "value" and "combined" cannot be non-NULL altogether, the change is not going to be so tremendous:

- const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
+ const size_t vallen = combined == NULL ? strlen (value) + 1 : 0;

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.