Обсуждение: BUG #12917: C program created by ecpg core dumped due to “varcharsize * offset”
BUG #12917: C program created by ecpg core dumped due to “varcharsize * offset”
От
chjischj@163.com
Дата:
The following bug has been logged on the website:
Bug reference: 12917
Logged by: Chen Huajun
Email address: chjischj@163.com
PostgreSQL version: 9.4.1
Operating system: RHEL6.5
Description:
I found a strange code in ecpg.
1)Problem 1
src/interfaces/ecpg/ecpglib/data.c:241
do
{
if (binary)
{
if (varcharsize == 0 || varcharsize * offset >= size)//!!! why
"varcharsize * offset" ? !!!
memcpy(var + offset * act_tuple, pval, size);
...
According to the mean of varcharsize(from the following comment),i think the
"varcharsize * offset >= size" above should be "varcharsize >= size" or
"offset >= size".
src\interfaces\ecpg\ecpglib\execute.c:
/*------
* create a list of variables
…
* varcharsize - length of string in case we have a stringvariable, else 0
* offset - offset between ith and (i+1)th entry in an array, normally
*------*/
2)Problem 2
And that,according to the comment above, the varcharsize should be setted to
0 for non stringvariable data type.
But the varcharsize is setted to 1 in C code which created by ecpg. Does
this a problem, or just my misunderstand ?
src\interfaces\ecpg\test\expected\sql-desc.c:81
#line 23 "desc.pgc"
{ ECPGset_desc(__LINE__, "indesc", 1,ECPGd_data,
ECPGt_int,&(val1),(long)1,(long)1,sizeof(int), ECPGd_EODT);
^^^^^^
3)Test
The problem 1 could cause memory overflow, as the following.
Environment:
PG 9.4.1
RHEL6.5
Table and data:
create table empl(idnum integer, name char (10000000));
insert into empl values(1,'abcdddd1123444ddffdfdffddfdfffd');
test app:
binary.pgc:
----------------------
#include <stdio.h>
#include <stdlib.h>
EXEC SQL BEGIN DECLARE SECTION;
struct TBempl
{
long idnum;
char name[10000];
};
EXEC SQL END DECLARE SECTION;
int main (void)
{
EXEC SQL BEGIN DECLARE SECTION;
struct TBempl empl;
EXEC SQL END DECLARE SECTION;
ECPGdebug (1, stderr);
empl.idnum = 1;
EXEC SQL connect to postgres USER postgres;
memset(empl.name, 0, 21L);
EXEC SQL DECLARE B BINARY CURSOR FOR select name from empl where idnum
=:empl.idnum;
EXEC SQL OPEN B;
EXEC SQL FETCH B INTO :empl.name;
EXEC SQL CLOSE B;
printf ("name=%s, byte=", empl.name);
printf("\n");
EXEC SQL disconnect;
exit (0);
}
Test:
export INCLUDE_PATH=/usr/local/pgsql/include
export LIB_PATH=/usr/local/pgsql/lib
export PATH=/usr/local/pgsql/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/pgsql/lib:$LD_LIBRARY_PATH
ecpg binary.pgc
gcc binary.c -o binary -I$INCLUDE_PATH -L$LIB_PATH -lecpg
./binary
[9547]: ECPGdebug: set to 1
[9547]: ECPGconnect: opening database regcob1 on <DEFAULT> port <DEFAULT>
for user postgres
[9547]: ecpg_execute on line 24: query: declare B binary cursor for select
name from empl where idnum = $1 ; with 1 parameter(s) on connection regcob1
[9547]: ecpg_execute on line 24: using PQexecParams
[9547]: ecpg_free_params on line 24: parameter 1 = 1
[9547]: ecpg_process_output on line 24: OK: DECLARE CURSOR
[9547]: ecpg_execute on line 25: query: fetch B; with 0 parameter(s) on
connection regcob1
[9547]: ecpg_execute on line 25: using PQexec
[9547]: ecpg_process_output on line 25: correctly got 1 tuples with 1
fields
[9547]: ecpg_get_data on line 25: RESULT: BINARY offset: 10000; array: no
セグメンテーション違反です (core dumped)
(gdb) bt
#0 0x0029557e in ecpg_get_data (results=0x8d673f8, act_tuple=0,
act_field=0, lineno=25, type=ECPGt_char, ind_type=ECPGt_NO_INDICATOR,
var=0xbfaa7bf0 "abcdddd1123444ddffdfdffddfdfffd", ' ' <repeats 169
times>..., ind=0x0, varcharsize=10000, offset=10000, ind_offset=0,
isarray=ECPG_ARRAY_NONE, compat=ECPG_COMPAT_PGSQL, force_indicator=1
'\001') at data.c:246
#1 0x0028d45e in ecpg_store_result (results=0x8d673f8, act_field=0,
stmt=0x8d667e0, var=0x8d66820) at execute.c:455
#2 0x00290770 in ecpg_process_output (stmt=0x8d667e0, clear_result=1
'\001') at execute.c:1693
#3 0x002911cc in ecpg_do (lineno=25, compat=0, force_indicator=1,
connection_name=0x0, questionmarks=0 '\000', st=0,
query=0x8048908 "fetch B", args=0xbfaa7bac "\033") at execute.c:2056
#4 0x0029125a in ECPGdo (lineno=25, compat=0, force_indicator=1,
connection_name=0x0, questionmarks=0 '\000', st=0,
query=0x8048908 "fetch B") at execute.c:2078
#5 0x08048749 in main ()
(gdb) list
241 do
242 {
243 if (binary)
244 {
245 if (varcharsize == 0 || varcharsize * offset >= size)
246 memcpy(var + offset * act_tuple, pval, size); //!!! core dumped here
!!!
247 else
248 {
249 memcpy(var + offset * act_tuple, pval, varcharsize * offset);
250
Re: BUG #12917: C program created by ecpg core dumped due to "varcharsize * offset"
От
Michael Paquier
Дата:
On Mon, Mar 30, 2015 at 8:13 PM, <chjischj@163.com> wrote:
>
> Table and data:
> create table empl(idnum integer, name char (10000000));
> insert into empl values(1,'abcdddd1123444ddffdfdffddfdfffd');
So the table used in your test uses char(10000000), which is a
datatype that completes with spaces strings stored that have a length
shorter than the limit. So even if you store a string of n characters,
what will be stored are those n characters, followed by 10,000,000 - n
spaces.
>
> EXEC SQL BEGIN DECLARE SECTION;
> struct TBempl
> {
> long idnum;
> char name[10000];
> };
And this test expects that result of column "name" does not contain
more 10k characters, so your data set is incompatible with your test,
explaining the crash you are seeing.
--
Michael
T24gMjAxNS0wNC0wNiAxMDoyMyAsIE1pY2hhZWwgUGFxdWllciBXcm90ZTogQW5kIHRoaXMgdGVz dCBleHBlY3RzIHRoYXQgcmVzdWx0IG9mIGNvbHVtbiAibmFtZSIgZG9lcyBub3QgY29udGFpbiBt b3JlIDEwayBjaGFyYWN0ZXJzLCBzbyB5b3VyIGRhdGEgc2V0IGlzIGluY29tcGF0aWJsZSB3aXRo IHlvdXIgdGVzdCwgZXhwbGFpbmluZyB0aGUgY3Jhc2ggeW91IGFyZSBzZWVpbmcuIC0tIE1pY2hh ZWwgLS0tLS0tLS0tLS0tLS0tIFRoYW5rcyBmb3IgeW91ciBhbnN3ZXIsYnV0IGkgc3RpbGwgY2Fu IG5vdCB1bmRlcnN0YW5kIHdoeSBoZXJlIGlzICJ2YXJjaGFyc2l6ZSAqIG9mZnNldCA+PSBzaXpl Iiwgd2hpbGUgaW4gdGhlIG5vbiBiaW5hcnkgYnJhbmNoIHRoYXQgaXMgInZhcmNoYXJzaXplID49 IHNpemUiIGFuZCB3b3JrcyBmaW5lIG9uIHRoZSBzYW1lIHRlc3QgY2FzZSh0cnVuY2F0ZSBzaXpl IHRvIHZhcmNoYXJzaXplKS7CoCBiaW5hcnkucGdjOsKgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS3C oCDCoEVYRUMgU1FMIERFQ0xBUkUgQiBCSU5BUlkgQ1VSU09SIEZPUiBzZWxlY3QgbmFtZSBmcm9t IGVtcGwgd2hlcmUgaWRudW0gPTplbXBsLmlkbnVtO8KgID09Pih0aGUgbm9uIGJpbmFyeSBicmFu Y2ggd29ya3MgZmluZSnCoCDCoEVYRUMgU1FMIERFQ0xBUkUgQiBDVVJTT1IgRk9SIHNlbGVjdCBu YW1lIGZyb20gZW1wbCB3aGVyZSBpZG51bSA9OmVtcGwuaWRudW07wqAgc3JjL2ludGVyZmFjZXMv ZWNwZy9lY3BnbGliL2RhdGEuYzo0NjbCoCBpZiAoYmluYXJ5KcKgIHvCoCDCoCDCoCDCoGlmICh2 YXJjaGFyc2l6ZSA9PSAwIHx8IHZhcmNoYXJzaXplICogb2Zmc2V0ID49IHNpemUpwqAgwqAgwqAg wqDCoCDCoCDCoG1lbWNweSh2YXIgKyBvZmZzZXQgKiBhY3RfdHVwbGUsIHB2YWwsIHNpemUpOy8v ISEhIG1lbW9yeSBvdmVyZmxvdyBmb3IgQklOQVJZIENVUlNPUiAhISHCoCDCoCDCoCDCoGVsc2XC oCDCoCDCoCDCoHvCoCDCoCDCoCDCoMKgIMKgIMKgbWVtY3B5KHZhciArIG9mZnNldCAqIGFjdF90 dXBsZSwgcHZhbCwgdmFyY2hhcnNpemUgKiBvZmZzZXQpO8KgIMKgIMKgIMKgIMKgLi4uwqAgwqAg wqAgwqAgwqB9wqAgLi4uwqAgfcKgIGVsc2XCoCB7wqAgLi4uwqAgwqAgwqAgwqBpZiAodmFyY2hh cnNpemUgPT0gMCB8fCB2YXJjaGFyc2l6ZSA+IHNpemUpwqAgwqAgwqAgwqB7wqAgwqAgwqAgwqDC oCDCoCDCoHN0cm5jcHkoc3RyLCBwdmFsLCBzaXplICsgMSk7wqAgwqAgwqAgwqAuLi7CoCDCoCDC oCDCoH3CoCDCoCDCoCDCoGVsc2XCoCDCoCDCoCDCoHvCoCDCoCDCoCDCoMKgIMKgIMKgc3RybmNw eShzdHIsIHB2YWwsIHZhcmNoYXJzaXplKTsvLyEhISB0cnVuY2F0ZSBzaXplIHRvIHZhcmNoYXJz aXplIGZvciBOT04gQklOQVJZIENVUlNPUiAhISHCoCDCoCDCoCDCoC4uLsKgIMKgIMKgIMKgfcKg IC4uLsKgIC0twqAgUmVnYXJkcywgQ2hlbiBIdWFqdW4=