Subject: | Buffer overflow with question marks in dash-style one line comments |
Date: | Thu, 6 Mar 2014 17:13:54 +0000 |
To: | "bug-DBD-DB2 [...] rt.cpan.org" <bug-DBD-DB2 [...] rt.cpan.org> |
From: | "Blohm, Guntram (I/FP-37, extern)" <extern.guntram.blohm [...] audi.de> |
This happened to me using a CentOS 6.5 system, the newest DBD::DB2 (V1.85), Perl 5.10.1 as provided by the distribution, and the 10.1 Fixpack 3 DS Driver.
My minimal test program is
use DBI;
use DBD::DB2;
my $string="dbi:DB2:OS5721P";
foo::bar();
package foo;
sub bar() {
my $dbh=DBI->connect($string, "xxxxxxx", "yyyyyyy");
my $sth=$dbh->prepare(qq(
select
-- ??? is it ok to try this ???
*
from sysibm.sysdummy1
where ? = 1
));
$sth->execute(1,2,3,4,5,6,7);
while (my(@f)=$sth->fetchrow_array()) {
print join(",", @f), "\n";
}
}
(I had to move the DB2 code into a different package to force perl to clean everything up, i couldn't reproduce the SIGSEGV without the package).
The problem i encountered is the comment string that contains question marks. Preparing the statement will call db2_st_prepare, in dbdimp.c line 2116. db2_st_prepare determines the number of parameters - 1 - connectly and puts this value into DBIc_NUM_PARAMS(imp_sth), then calls dbd_preparse() in line 2155.
dbd_preparse will try to replace the question mark parameters with :pX parameters, with X being an index, so it calculates the size needed for the new string and allocates memory for that new string (Line 1397). The new length is basically strlen(query)+DBIc_NUM_PARAMS*2, plus some space to handle more than 10 parameters.
Then, dbd_preparse copies the original string to the new allocated buffer, replacing the ? identifiers with :pX. This replacement routine handles /* */ comments and string literals well, but it doesn't handle -- style comments. So, after replacement, the new string from my example program will be
select
-- :p1:p2:p3 is it ok to try this :p4:p5:p6
*
from sysibm.sysdummy1
where :p7 = 1
However, the initial length calculation assumes just 1 parameter, so the allocated length is 88 + 3 bytes (88 from strlen of the original string, 3 for expansion), while the real length of the result string is 102, resulting in buffer overflow, and various kinds of errors later. (Also, the number of positional parameters is changed to 7, so i can't execute the statement with one parameter as i should).
My workaround, for now, is not using question mark characters in dash-style comments, but i suggest handling this kind of comments by not copying them to the result string, treating them just like /**/ comments.
Sincerely,
Guntram Blohm