This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug libc/4887] New: Wordexp() should be thread safe.
- From: "t-nishiie at soft dot fujitsu dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sources dot redhat dot com
- Date: 3 Aug 2007 02:21:10 -0000
- Subject: [Bug libc/4887] New: Wordexp() should be thread safe.
- Reply-to: sourceware-bugzilla at sourceware dot org
Wordexp() should be thread safe.
1. Summary:
wordexp() should be thread safe.
However, because wordexp() calls setenv()/unsetenv() internally,
wordexp() is not actually thread safe.
2. hardware dependency:
none.
3. Description of Problem:
As IEEE Std 10003.1-20001 says, wordexp() should be thread
safe. See the following URL:
http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html
However, when wordexp() is called simultaneously with another
MT-safe functions which uses getenv() internally among functions
defined by glibc, the following problems may occur:
Problem No.1:
getenv() may generate SIGSEGV.
Problem No.2:
getenv() sometimes fails to acquire the environment variable.
4. How reproducible:
Always
5. Step to Reproduce:
The following test program can reproduce the problems.
tst-wordexp.tar.gz
To make reproduction easy, this program executes wordexp()
and getenv() at the same time by a lot of threads.
1) Extract the archive file.
The following files are extracted.
Makefile
tst-wordexp.c
2) Compile the test program.
# make
3) Run the test program.
# ./tst-wordexp
- If Problem No.1 occurs, the test program will be
terminated by segmentation fault.
- If Problem No.2 happens, the test program will
display the following messages.
Example:
A00019 getenv V03077=NULL
This message means getenv("V03077") returned NULL
though the test program had defined V03077 as an
environment variable beforehand.
6. Actual Results:
Example:
# ./tst-setenv
A00019 getenv V03077=NULL
A00473 getenv V03699=NULL
A00173 getenv V04256=NULL
A00099 getenv V03367=NULL
A00267 getenv V03899=NULL
Segmentation fault
#
7. Expected Resulst:
# ./tst-setenv
end
#
8. Cause
Glibc contains a lot of functions assumed to be thread safe
which executes getenv(). These problems occur because
wordexp() indirectly executes setenv() and getenv() from
different threads at the same time. As for unsetenv(),
it is similar.
Problem No.1:
- wordexp() may call setenv()
- On adding a new environment variable, the memory block
bound to __environ is changed by realloc(). Hence calling
getenv() simultaneously with setenv() may access freed
memory block and cause SIGSEGV.
Problem No.2:
- wordexp() may call unsetenv()
- On calling unsetenv(), the contents in the __environ is
shifted one by one to delete an element. Hence calling
getenv() simultaneously with unsetenv() may skip existing
element.
9. Solutions
I propose a following patch.
glibc-setenv-fj20070713.patch
This patch solves the problems when setenv()/unsetenv()
and getenv() are called at the same time.
Problem No.1:
- This correction reduces frequency to acquire the memory
block bound to __environ.
- If the memory block bound to __environ is exhausted, new
block is allocated but previous one is not released to
avoid SIGSEGV. In addition, the size of new block is
doubled to avoid aquiring memory on every environment
variable addition.
Problem No.2:
- This correction does not shift elements bounding to
__environ as much as possible.
- Not to shift elements on unsetenv(), the element going
to be deleted is not deleted but overwritten by copy of
other element instead.
--
Summary: Wordexp() should be thread safe.
Product: glibc
Version: unspecified
Status: NEW
Severity: normal
Priority: P2
Component: libc
AssignedTo: drepper at redhat dot com
ReportedBy: t-nishiie at soft dot fujitsu dot com
CC: glibc-bugs at sources dot redhat dot com,t-nishiie at
soft dot fujitsu dot com
http://sourceware.org/bugzilla/show_bug.cgi?id=4887
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.