Bug #14016 Updated: Double efree bug in 4.0.6 pgsql.so makes NOTICE msgs crash httpd eventually
| From: | sniper@php.net | Date: | Mon, 12 Nov 2001 01:01:08 +0000 |
| Subject: | Bug #14016 Updated: Double efree bug in 4.0.6 pgsql.so makes NOTICE msgs crash httpd eventually | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-70186@lists.php.net to get a copy of this message | ||
ID: 14016
Updated by: sniper
Reported By: dan.franklin@learningnetwork.com
Old Status: Open
Status: Closed
Bug Type: Reproducible crash
Operating System: Linux Redhat 6.2, 7.1
PHP Version: 4.0.6
New Comment:
This is fixed in CVS. Try the latest CVS snapshot from
http://snaps.php.net/ to verify it. Reopen if it doesn't
work.
--Jani
Previous Comments:
------------------------------------------------------------------------
[2001-11-11 16:38:53] dan.franklin@learningnetwork.com
Here is a short script that makes my httpd crash about 1/3 of the time. Reduce the number of httpd
server processes to 1 or 2 or you may have to execute it many times before it starts crashing.
Correct output: several hundred lines of "A reasonably long string..." mostly separated by
blank lines.
Observed output about 1/3 of the time: an EOF before any status message returned.
<script language="php">
// Alter connect line to match a database of yours
$connect_str = "host=... dbname=tv user=webadmin...";
$c = pg_connect($connect_str);
for ($i = 0; $i < 20; $i++) {
$array[$i] = "A reasonably long string to make sure that allocations happen
$i<br>\n";
}
// Trigger some NOTICE messages, allocate storage in between
$big = '';
for ($i = 0; $i < 20; $i++) {
// This triggers a NOTICE message about the primary key
$rc = pg_exec($c, "create table testing ( c int4 primary key )");
// drop table for next iteration
$rc = pg_exec($c, "drop table testing");
// close connection, triggering efree(last_notice)
pg_close($c);
// reconnect
$c = pg_connect($connect_str);
// do something to allocate lots of storage
$big .= join("\n", $array);
}
// use the allocated storage
print "$big\n";
</script>
Configuration: Apache 1.3.20 on Linux RH 6.2 or 7.1 (this script "works" on both).
PostgreSQL 7.1.3. PHP configured with:
'./configure' '--prefix=/usr' '--with-apxs'
'--libdir=/usr/lib/php4' '--includedir=/usr/include'
'--datadir=/usr/share/php' '--with-config-file-path=/etc'
'--enable-inline-optimization' '--enable-magic-quotes'
'--enable-track-vars' '--enable-memory-limit' '--enable-bcmath'
'--with-gdbm' '--with-xml' '--with-expat-dir=/usr'
'--with-mm' '--with-openssl' '--with-gd=shared,/usr'
'--enable-sysvsem=shared' '--enable-sysvshm=shared'
'--enable-shmop=shared' '--with-gettext=shared' '--with-pspell=shared'
'--enable-sockets=shared' '--enable-wddx' '--enable-apc=shared'
'--with-zlib=/usr'
------------------------------------------------------------------------
[2001-11-11 09:53:17] dan.franklin@learningnetwork.com
It's difficult to provide a short script for this since it's a storage problem - but it
happens very consistently in our setup, eliminating the NOTICE messages caused the crashes to stop,
and I believe I know where the bug is.
Take a look at php-4.0.6/ext/pgsql/pgsql.c. Observe that it has a static pointer
"last_notice" that holds a copy, allocated via estrdup, of the most recent PostgreSQL
notice message. It frees this copy when it receives a new one. It tests the pointer against NULL
to determine whether to free it - but after freeing it with efree, does not set the pointer to NULL
again. Thus it is possible to call efree twice on the same storage. Since that storage may have
been reallocated in other parts of the code, freeing it here can be (and is) disastrous if httpd
runs long enough.
I will create a test script that crashes consistently if necessary.
------------------------------------------------------------------------
Edit this bug report at http://bugs.php.net/?id=14016&edit=1