php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #14016 Double efree bug in 4.0.6 pgsql.so makes NOTICE msgs crash httpd eventually
Submitted: 2001-11-11 09:53 UTC Modified: 2001-11-11 20:01 UTC
From: dan dot franklin at learningnetwork dot com Assigned:
Status: Closed Package: PostgreSQL related
PHP Version: 4.0.6 OS: Linux Redhat 6.2, 7.1
Private report: No CVE-ID: None
 [2001-11-11 09:53 UTC] dan dot franklin at learningnetwork dot 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.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2001-11-11 16:38 UTC] dan dot franklin at learningnetwork dot 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 20:01 UTC] sniper@php.net
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

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Apr 27 20:01:29 2024 UTC