Re: crash in DBD::mysql/ statement leak in DBD::mysql

Patrick Galbraith <[email protected]> Mon, 21 May 2007 09:18:49 -0400
Newsgroups gmane.comp.db.mysql.perl
Message-ID <[email protected]>
Rainer,

Thanks for the patch! I will test it this week against various versions 
of MySQL.

Regards,

Patrick

Rainer Weikusat wrote:

>This applies to the current CPAN-version of the DBD::mysql module.
>
>When using server side prepared statements, storage for 'bind values'
>is allocated in dbd_st_prepare and freed in dbd_st_finish after all
>rows resulting from one execution of a query have been fetched. This
>means the next attempt to execute the prepared statement will
>segfault when trying to use those storage.
>
>Fix for this issue: Move the freeing-code to the dbd_st_destroy
>routine. 
>
>Additionally, the person who delete the 'free everything' code from
>dbd_st_destroy accidentally deleted the once line of code that was
>different from the similar chunk in dbd_st_finish, namely, the
>mysql_stmt_close call, meaning, prepared statements are leaked in the
>server.
>
>Fix for this issue: Re-add mysql_stmt_close in dbd_st_destroy.
>
>The attached patch does both of this.
>
>NB: Both of this issues have already been reported as bugs, but
>apparently, the responsible person believed that the first doesn't
>actually exist and for the second, a patch has been proposed which
>would make the thing worse (calling mysql_stmt_close in finish will
>prevent re-executing prepared select statements after all results of
>one execution have been fetched). Additionally, the patch implements
>only the two fixes and not a larger set of 'random other changes',
>like the one for #1 available from the Mysql-BTS did.
>
>  
>
>------------------------------------------------------------------------
>
>diff -rNu DBD-mysql.cpan/dbdimp.c DBD-mysql/dbdimp.c
>--- DBD-mysql.cpan/dbdimp.c	2007-05-21 10:07:12.000000000 +0200
>+++ DBD-mysql/dbdimp.c	2007-05-21 12:30:27.000000000 +0200
>@@ -3720,10 +3720,6 @@
> #endif
> 
> #if MYSQL_VERSION_ID >= SERVER_PREPARE_VERSION
>-  int i;
>-  int num_fields;
>-  imp_sth_fbh_t *fbh;
>-
>   if (dbis->debug >= 2)
>   {
>     PerlIO_printf(DBILOGFP, "\n--> dbd_st_finish\n");
>@@ -3740,32 +3736,6 @@
>         return 0;
>       }
>     }
>-    /* clean up other statement allocations */
>-    if (DBIc_NUM_PARAMS(imp_sth) > 0)
>-    {
>-      if (dbis->debug >= 2)
>-        PerlIO_printf(DBILOGFP,
>-                      "\tFreeing %d parameters\n",
>-                      DBIc_NUM_PARAMS(imp_sth));
>-      free_bind(imp_sth->bind);
>-      free_fbind(imp_sth->fbind);
>-      imp_sth->bind= NULL;
>-      imp_sth->fbind= NULL;
>-    }
>-    num_fields= DBIc_NUM_FIELDS(imp_sth);
>-
>-    if (imp_sth->fbh)
>-    {
>-      for (fbh= imp_sth->fbh, i= 0; i < num_fields; i++, fbh++)
>-      {
>-        if (fbh->data)
>-          Safefree(fbh->data);
>-      }
>-      free_fbuffer(imp_sth->fbh);
>-      free_bind(imp_sth->buffer);
>-      imp_sth->buffer= NULL;
>-      imp_sth->fbh= NULL;
>-    }
>   }
> #endif
> 
>@@ -3812,6 +3782,47 @@
> 
>   int i;
> 
>+#if MYSQL_VERSION_ID >= SERVER_PREPARE_VERSION
>+  imp_sth_fbh_t *fbh;
>+  int n;
>+  
>+  n = DBIc_NUM_PARAMS(imp_sth);
>+  if (n)
>+  {
>+    if (dbis->debug >= 2)
>+      PerlIO_printf(DBILOGFP, "\tFreeing %d parameters\n",
>+		    n);
>+
>+    free_bind(imp_sth->bind);
>+    free_fbind(imp_sth->fbind);
>+  }
>+
>+  fbh = imp_sth->fbh;
>+  if (fbh)
>+  {
>+    n = DBIc_NUM_FIELDS(imp_sth);
>+    i = 0;
>+    while (i < n)
>+    {
>+      if (fbh[i].data) Safefree(fbh[i].data);
>+      ++i;
>+    }
>+
>+    free_fbuffer(fbh);
>+    free_bind(imp_sth->buffer);
>+  }
>+  
>+  if (imp_sth->stmt)
>+  {
>+    if (!mysql_stmt_close(imp_sth->stmt))
>+    {
>+        do_error(DBIc_PARENT_H(imp_sth), mysql_stmt_errno(imp_sth->stmt),
>+                 mysql_stmt_error(imp_sth->stmt),
>+                 mysql_stmt_sqlstate(imp_sth->stmt));
>+    }
>+  }
>+#endif
>+
>   /* dbd_st_finish has already been called by .xs code if needed.	*/
> 
>   /* Free values allocated by dbd_bind_ph */
>
>  
>
>------------------------------------------------------------------------
>
>
>  
>


-- 
Patrick Galbraith, Senior Programmer 
Grazr - Easy feed grazing and sharing
http://www.grazr.com 

Satyam Eva Jayate - Truth Alone Triumphs
Mundaka Upanishad




-- 
MySQL Perl Mailing List
For list archives: http://lists.mysql.com/perl
To unsubscribe:    http://lists.mysql.com/[email protected]