Bug #14016 Updated: Double efree bug in 4.0.6 pgsql.so makes NOTICE msgs crash httpd eventually
| From: | dan dot franklin at learningnetwork dot com | Date: | Sun, 11 Nov 2001 21:38:54 +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-70170@lists.php.net to get a copy of this message | ||
ID: 14016
User updated by: dan.franklin@learningnetwork.com
Reported By: dan.franklin@learningnetwork.com
Status: Open
Bug Type: Reproducible crash
Operating System: Linux Redhat 6.2, 7.1
PHP Version: 4.0.6
New Comment:
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'
Previous Comments:
------------------------------------------------------------------------
[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