Обсуждение: [BUGS] BUG #14582: ecpg crashes on SQL input
The following bug has been logged on the website: Bug reference: 14582 Logged by: Michael Dudley Email address: mdudley@gryphonsensors.com PostgreSQL version: 9.6.2 Operating system: CentOS 7.3.1611 Description: I have some SQL that crashes ecpg when I run: $ cat test.sql | /usr/pgsql-9.6/bin/ecpg -o - - I installed PostgreSQL from "postgresql96-server-9.6.2-2PGDG.rhel7.x86_64.rpm". There are trailing spaces on some lines in the SQL below--they are necessary in order to reproduce the crash. test.sql ------------------------------------------------------------------------ EXEC SQL INSERT INTO x (y) VALUES (''); EXEC SQL DROP FUNCTION IF EXISTS a() CASCADE; EXEC SQL CREATE OR REPLACE FUNCTION a() RETURNS uuid AS $$ DECLARE b uuid; EXEC SQL BEGIN WITH a AS (SELECT uuid_generate_v1() AS id), xxxxxxxx_xxxxxx_xxxxx_xxxxxxx AS ( INSERT INTO xxxxxxxx_xxxxxx_xxxxx( xxxxxx_xx, xxxx_xxxxxxxxxxxxx_xx, xxxxxx_xxxxxxxxxxx_xxx_xx, xxxxxxxxxxx_xx, xxxxxxxx_xxxxxxxx_xxxxxx_xxxxx_xx) VALUES ( ( SELECT x_xx FROM xxxxxxx_xxxxxx LIMIT 1 ), ( SELECT xxxx_xxxxxxxxxxxxx_xx FROM xxxxxx LIMIT 1 ), ( SELECT xxxxxx_xxxxxxxxxxx_xxx_xx FROM xxxxxxx_xxxxxx_xxxxxxxxxxx LIMIT 1 ), ( SELECT id FROM xxxxxxx_xxxxxxxxxxx LIMIT 1 ), ( SELECT id FROM x ) ) RETURNING xxxxx_xxxx ) SELECT id INTO b FROM a; EXEC SQL RETURN b; EXEC SQL END; EXEC SQL $$ LANGUAGE plpgsql;; EXEC SQL CREATE OR REPLACE FUNCTION xxxxxx_xxxxxx_xxxxxxxxxx() RETURNS trigger AS $$ BEGIN PERFORM x(); EXEC SQL RETURN NEW; EXEC SQL END; EXEC SQL $$ LANGUAGE plpgsql;; ------------------------------------------------------------------------ Crash output: ------------------------------------------------------------------------ $ cat test-filtered.sql | /usr/pgsql-9.6/bin/ecpg -o - - /* Processed by ecpg (4.12.0) */ /* These include files are added by the preprocessor */ #include <ecpglib.h> #include <ecpgerrno.h> #include <sqlca.h> /* End of automatic include section */ #line 1 "stdin" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "insert into x ( y ) values ( '' )", ECPGt_EOIT, ECPGt_EORT);} #line 2 "stdin" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "drop function if exists a ( ) cascade", ECPGt_EOIT, ECPGt_EORT);} #line 4 "stdin" { ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "create or replace function a ( ) returns uuid as $$\ DECLARE\ b uuid;\ EXEC SQL BEGIN\ WITH\ a AS (SELECT uuid_generate_v1() AS id),\ xxxxxxxx_xxxxxx_xxxxx_xxxxxxx AS \ (\ INSERT INTO xxxxxxxx_xxxxxx_xxxxx(\ xxxxxx_xx, \ xxxx_xxxxxxxxxxxxx_xx, \ xxxxxx_xxxxxxxxxxx_xxx_xx,\ xxxxxxxxxxx_xx, \ xxxxxxxx_xxxxxxxx_xxxxxx_xxxxx_xx)\ VALUES ( \ ( SELECT x_xx FROM xxxxxxx_xxxxxx LIMIT 1 ), \ ( SELECT xxxx_xxxxxxxxxxxxx_xx FROM xxxxxx LIMIT 1 ), \ ( SELECT xxxxxx_xxxxxxxxxxx_xxx_xx FROM xxxxxxx_xxxxxx_xxxxxxxxxxx LIMIT 1 ),\ ( SELECT id FROM xxxxxxx_xxxxxxxxxxx LIMIT 1 ),\ ( SELECT id FROM x ) )\ RETURNING xxxxx_xxxx\ )\ SELECT id INTO b FROM a;\ \ EXEC SQL RETURN b;\ EXEC SQL END;\ EXEC SQL $$ language plpgsql", ECPGt_EOIT, ECPGt_EORT);} #line 32 "stdin" ; *** Error in `/usr/pgsql-9.6/bin/ecpg': double free or corruption (fasttop): 0x0000000001e3a970 *** ======= Backtrace: ========= /lib64/libc.so.6(+0x7c503)[0x7f5cfe585503] /usr/pgsql-9.6/bin/ecpg[0x401b84] /usr/pgsql-9.6/bin/ecpg[0x401c16] /usr/pgsql-9.6/bin/ecpg[0x4048ba] /usr/pgsql-9.6/bin/ecpg[0x403112] /lib64/libc.so.6(__libc_start_main+0xf5)[0x7f5cfe52ab35] /usr/pgsql-9.6/bin/ecpg[0x403885] ======= Memory map: ======== 00400000-004d3000 r-xp 00000000 fd:00 73095339 /usr/pgsql-9.6/bin/ecpg 006d2000-006d3000 r--p 000d2000 fd:00 73095339 /usr/pgsql-9.6/bin/ecpg 006d3000-006d4000 rw-p 000d3000 fd:00 73095339 /usr/pgsql-9.6/bin/ecpg 006d4000-006d6000 rw-p 00000000 00:00 0 01e35000-01e56000 rw-p 00000000 00:00 0 [heap] 7f5cf0000000-7f5cf0021000 rw-p 00000000 00:00 0 7f5cf0021000-7f5cf4000000 ---p 00000000 00:00 0 7f5cf7dca000-7f5cf7ddf000 r-xp 00000000 fd:00 101072955 /usr/lib64/libgcc_s-4.8.5-20150702.so.1 7f5cf7ddf000-7f5cf7fde000 ---p 00015000 fd:00 101072955 /usr/lib64/libgcc_s-4.8.5-20150702.so.1 7f5cf7fde000-7f5cf7fdf000 r--p 00014000 fd:00 101072955 /usr/lib64/libgcc_s-4.8.5-20150702.so.1 7f5cf7fdf000-7f5cf7fe0000 rw-p 00015000 fd:00 101072955 /usr/lib64/libgcc_s-4.8.5-20150702.so.1 7f5cf7fe0000-7f5cfe509000 r--p 00000000 fd:00 100762636 /usr/lib/locale/locale-archive 7f5cfe509000-7f5cfe6bf000 r-xp 00000000 fd:00 100711660 /usr/lib64/libc-2.17.so 7f5cfe6bf000-7f5cfe8bf000 ---p 001b6000 fd:00 100711660 /usr/lib64/libc-2.17.so 7f5cfe8bf000-7f5cfe8c3000 r--p 001b6000 fd:00 100711660 /usr/lib64/libc-2.17.so 7f5cfe8c3000-7f5cfe8c5000 rw-p 001ba000 fd:00 100711660 /usr/lib64/libc-2.17.so 7f5cfe8c5000-7f5cfe8ca000 rw-p 00000000 00:00 0 7f5cfe8ca000-7f5cfe8e1000 r-xp 00000000 fd:00 101379652 /usr/lib64/libpthread-2.17.so 7f5cfe8e1000-7f5cfeae0000 ---p 00017000 fd:00 101379652 /usr/lib64/libpthread-2.17.so 7f5cfeae0000-7f5cfeae1000 r--p 00016000 fd:00 101379652 /usr/lib64/libpthread-2.17.so 7f5cfeae1000-7f5cfeae2000 rw-p 00017000 fd:00 101379652 /usr/lib64/libpthread-2.17.so 7f5cfeae2000-7f5cfeae6000 rw-p 00000000 00:00 0 7f5cfeae6000-7f5cfeb06000 r-xp 00000000 fd:00 100762635 /usr/lib64/ld-2.17.so 7f5cfecea000-7f5cfeced000 rw-p 00000000 00:00 0 7f5cfed01000-7f5cfed05000 rw-p 00000000 00:00 0 7f5cfed05000-7f5cfed06000 r--p 0001f000 fd:00 100762635 /usr/lib64/ld-2.17.so 7f5cfed06000-7f5cfed07000 rw-p 00020000 fd:00 100762635 /usr/lib64/ld-2.17.so 7f5cfed07000-7f5cfed08000 rw-p 00000000 00:00 0 7ffed102c000-7ffed104d000 rw-p 00000000 00:00 0 [stack] 7ffed10a3000-7ffed10a5000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted (core dumped) ------------------------------------------------------------------------ -- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs
> I have some SQL that crashes ecpg when I run: > ... > There are trailing spaces on some lines in the SQL below--they are > necessary > in order to reproduce the crash. Could you please resend the file as attachment? Ideally gzipped or so? We need to make sure to test with exactly the same file and I'd like to not worry about the MTA/MUA/whathaveyou having changed a blank. Thanks. Michael -- Michael Meskes Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org) Meskes at (Debian|Postgresql) dot Org Jabber: michael at xmpp dot meskes dot org VfL Borussia! Força Barça! SF 49ers! Use Debian GNU/Linux, PostgreSQL -- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs
Sure--see attached. Luckily enough, copying the SQL from the pgsql-bugs archive reproduces the problem as well. -----Original Message----- From: Michael Meskes [mailto:meskes@postgresql.org] Sent: Thursday, 09 March, 2017 8:24 AM To: Dudley, Michael <mdudley@gryphonsensors.com> Cc: pgsql-bugs@postgresql.org Subject: Re: [BUGS] BUG #14582: ecpg crashes on SQL input Notice: This message originated outside of SRC. > I have some SQL that crashes ecpg when I run: > ... > There are trailing spaces on some lines in the SQL below--they are > necessary in order to reproduce the crash. Could you please resend the file as attachment? Ideally gzipped or so? We need to make sure to test with exactly the same file and I'd like to not worry about the MTA/MUA/whathaveyou having changeda blank. Thanks. Michael -- Michael Meskes Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org) Meskes at (Debian|Postgresql) dot Org Jabber: michael at xmpp dot meskes dot org VfL Borussia! Força Barça! SF 49ers! Use Debian GNU/Linux, PostgreSQL -- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs
Вложения
2017-03-08 13:56 GMT-03:00 <mdudley@gryphonsensors.com>:
I have some SQL that crashes ecpg when I run:
$ cat test.sql | /usr/pgsql-9.6/bin/ecpg -o - -
I installed PostgreSQL from
"postgresql96-server-9.6.2-2PGDG.rhel7.x86_64.rpm".
There are trailing spaces on some lines in the SQL below--they are necessary
in order to reproduce the crash.
I reproduced the crash only with 9.6 and 9.5 (didn't try hard with other supported versions but they don't crash -- including HEAD) with the attached file extracted from your email (some email clients mangles your test). The crash seems to be related to the blank line in the middle of the above command (altough, few spaces doesn't crash the test). In a rapid test, a line with > 40 spaces produces the crash.
INSERT INTO xxxxxxxx_xxxxxx_xxxxx(\
xxxxxx_xx, \
xxxx_xxxxxxxxxxxxx_xx, \
xxxxxx_xxxxxxxxxxx_xxx_xx,\
xxxxxxxxxxx_xx, \
xxxxxxxx_xxxxxxxx_xxxxxx_xxxxx_xx)\
VALUES ( \
( SELECT x_xx FROM xxxxxxx_xxxxxx LIMIT 1 ), \
( SELECT xxxx_xxxxxxxxxxxxx_xx FROM xxxxxx LIMIT 1 ),
The backtrace is:
(gdb) bt
#0 0x00007ff67829e067 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/
#1 0x00007ff67829f448 in __GI_abort () at abort.c:89
#2 0x00007ff6782dc1b4 in __libc_message (do_abort=do_abort@entry=1, fmt=fmt@entry=0x7ff6783d1210 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:
#3 0x00007ff6782e198e in malloc_printerr (action=1, str=0x7ff6783d13f8 "double free or corruption (fasttop)", ptr=<optimized out>) at malloc.c:4996
#4 0x00007ff6782e2696 in _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3840
#5 0x0000000000401a4d in cat2_str (str1=<optimized out>, str2=<optimized out>) at preproc.y:145
#6 0x0000000000401ad2 in cat_str (count=9) at preproc.y:162
#7 0x000000000040eb80 in base_yyparse () at preproc.y:6731
#8 0x0000000000403113 in main (argc=4, argv=0x7fff016f3ff8) at ecpg.c:452
--
Euler Taveira Timbira - http://www.timbira.com.br/
PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento
PostgreSQL: Consultoria, Desenvolvimento, Suporte 24x7 e Treinamento
Вложения
> Sure--see attached. > > Luckily enough, copying the SQL from the pgsql-bugs archive > reproduces the problem as well. Could you try the attached patch please? Michael -- Michael Meskes Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org) Meskes at (Debian|Postgresql) dot Org Jabber: michael at xmpp dot meskes dot org VfL Borussia! Força Barça! SF 49ers! Use Debian GNU/Linux, PostgreSQL -- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs
Вложения
Michael Meskes <meskes@postgresql.org> writes: > Could you try the attached patch please? Wow, that's certainly a bug fix, and it does stop the crash in 9.6 for me, but I'm not sure that I follow how come the failure seems to be version- and data-dependent. It looks like, because of this bug, you ought to reliably have a double free() occurring any time there's more than one dollar-quoted constant in ecpg's input. Why doesn't glibc notice? I think that in most cases, the malloc block used for dolqstart would have been handed out again for another temporary string by the time we reach the second dollar-quoted constant, so the second free(dolqstart) in itself wouldn't look like an error to glibc. But when the temporary string is freed for real, a bit later, that should result in an error. Does ecpg leak a large fraction of its temporary strings? regards, tom lane -- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs
I wrote: > Wow, that's certainly a bug fix, and it does stop the crash in 9.6 for me, > but I'm not sure that I follow how come the failure seems to be version- > and data-dependent. It looks like, because of this bug, you ought to > reliably have a double free() occurring any time there's more than one > dollar-quoted constant in ecpg's input. Why doesn't glibc notice? After some googling, the answer seems to be that glibc's detection of double free() is really unreliable for small chunks. It will basically only notice an extra free of the same chunk most recently freed within a given bin (size range). Since in the problem at hand there are probably unrelated free's happening between the two free's mentioning the same chunk, it's quite easy for it to miss the error. I'm still a bit unsure why I see the crash in 9.6 but not HEAD, because there's very little difference between them, but I no longer feel that we need to investigate more closely. This all suggests that it might be worth testing ecpg with a debugging malloc library that has more robust error detection ... regards, tom lane -- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs
> After some googling, the answer seems to be that glibc's detection of > double free() is really unreliable for small chunks. It will > basically > only notice an extra free of the same chunk most recently freed > within a > given bin (size range). Since in the problem at hand there are > probably > unrelated free's happening between the two free's mentioning the same > chunk, it's quite easy for it to miss the error. I'm still a bit > unsure > why I see the crash in 9.6 but not HEAD, because there's very little > difference between them, but I no longer feel that we need to > investigate > more closely. On my system I don't see this segfault at all, unless I run it under valgrind. > This all suggests that it might be worth testing ecpg with a > debugging > malloc library that has more robust error detection ... I sometimes do. However, the library is more important imo, a leak in a short running application like ecpg itself does not do too much harm. Michael -- Michael Meskes Michael at Fam-Meskes dot De, Michael at Meskes dot (De|Com|Net|Org) Meskes at (Debian|Postgresql) dot Org Jabber: michael at xmpp dot meskes dot org VfL Borussia! Força Barça! SF 49ers! Use Debian GNU/Linux, PostgreSQL -- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs