BUG #3866: Segfault during table update when using convert_from()

Started by Andrew Gilliganover 18 years ago4 messagesbugs
Jump to latest
#1Andrew Gilligan
andy@tcpd.net

The following bug has been logged online:

Bug reference: 3866
Logged by: Andrew Gilligan
Email address: andy@tcpd.net
PostgreSQL version: 8.3RC1
Operating system: FreeBSD 4.11
Description: Segfault during table update when using convert_from()
Details:

Greetings,

It seems there exists a bug in the way character set conversion
is handled in some circumstances.

Running the test below results in the server (8.3RC1) segfaulting
every time. I haven't fully explored the extent, but it exists
with (at least) LATIN2 and LATIN9 conversion.

The database and client encoding are both UTF8.

Best regards,
-Andy

-- test case --
test=# CREATE TABLE t (id int, geo text);
CREATE TABLE
test=# INSERT INTO t (id, geo) VALUES (1,
convert_from(decode('50696f74726bf3772c20506f6c616e64','hex'), 'LATIN9'));
INSERT 0 1
test=# UPDATE t SET geo =
convert_from(decode('50696f74726bf3772c20506f6c616e64','hex'), 'LATIN9');
UPDATE 1
-- more than 1 row is needed to trigger the error
test=# INSERT INTO t (id, geo) VALUES (2,
convert_from(decode('50696f74726bf3772c20506f6c616e64','hex'), 'LATIN9'));
INSERT 0 1
test=# UPDATE t SET geo =
convert_from(decode('50696f74726bf3772c20506f6c616e64','hex'), 'LATIN9');
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
!>

#2Pavel Stehule
pavel.stehule@gmail.com
In reply to: Andrew Gilligan (#1)
Re: BUG #3866: Segfault during table update when using convert_from()

On 09/01/2008, Andrew Gilligan <andy@tcpd.net> wrote:

The following bug has been logged online:

Bug reference: 3866
Logged by: Andrew Gilligan
Email address: andy@tcpd.net
PostgreSQL version: 8.3RC1
Operating system: FreeBSD 4.11
Description: Segfault during table update when using convert_from()
Details:

Greetings,

It seems there exists a bug in the way character set conversion
is handled in some circumstances.

Running the test below results in the server (8.3RC1) segfaulting
every time. I haven't fully explored the extent, but it exists
with (at least) LATIN2 and LATIN9 conversion.

The database and client encoding are both UTF8.

Best regards,
-Andy

-- test case --
test=# CREATE TABLE t (id int, geo text);
CREATE TABLE
test=# INSERT INTO t (id, geo) VALUES (1,
convert_from(decode('50696f74726bf3772c20506f6c616e64','hex'), 'LATIN9'));
INSERT 0 1
test=# UPDATE t SET geo =
convert_from(decode('50696f74726bf3772c20506f6c616e64','hex'), 'LATIN9');
UPDATE 1
-- more than 1 row is needed to trigger the error
test=# INSERT INTO t (id, geo) VALUES (2,
convert_from(decode('50696f74726bf3772c20506f6c616e64','hex'), 'LATIN9'));
INSERT 0 1
test=# UPDATE t SET geo =
convert_from(decode('50696f74726bf3772c20506f6c616e64','hex'), 'LATIN9');
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
!>

I tested it without debug flags and server faults.

with --enable-debug and --enable-cassert I got
convert_from(decode('50696f74726bf3772c20506f6c616e64','hex'), 'LATIN9');
ERROR: 42622: encoding name too long
LOCATION: pg_char_to_encname_struct, encnames.c:515

postgres=# INSERT INTO t (id, geo) VALUES (2,
convert_from(decode('50696f74726bf3772c20506f6c616e64','hex'), 'LATIN9'));
INSERT 0 1
postgres=# UPDATE t SET geo =
convert_from(decode('50696f74726bf3772c20506f6c616e64','hex'), 'LATIN2');
ERROR: 42622: encoding name too long
LOCATION: pg_char_to_encname_struct, encnames.c:515
postgres=#

this problem is only in UPDATE statement

pg_char_to_encname_struct is called 3 times, 2times with correct name
and last time with garbage

Breakpoint 1, pg_char_to_encname_struct (
name=0x8bb3510 '\177' <repeats 64 times>, "���\b ") at encnames.c:496
496 unsigned int nel = pg_encname_tbl_sz;
(gdb) bt
#0 pg_char_to_encname_struct (
name=0x8bb3510 '\177' <repeats 64 times>, "���\b ") at encnames.c:496
#1 0x082e24dc in pg_char_to_encoding (
name=0x8bb3510 '\177' <repeats 64 times>, "���\b ") at encnames.c:550
#2 0x082e3ed8 in pg_convert (fcinfo=0xbfa237dc) at mbutils.c:362
#3 0x082d949e in DirectFunctionCall3 (func=0x82e3eb0 <pg_convert>,
arg1=146487356, arg2=146486544, arg3=146597884) at fmgr.c:1030
#4 0x082e3c24 in pg_convert_from (fcinfo=0xbfa23a38) at mbutils.c:336
#5 0x0818c563 in ExecMakeFunctionResultNoSets (fcache=0x8bccc64,
econtext=0x8bccb64, isNull=0x8bcd7a9 "", isDone=0x8bcd80c)
at execQual.c:1412
#6 0x081875d2 in ExecProject (projInfo=0x8bcd7bc, isDone=0xbfa23ce8)
at execQual.c:4601
#7 0x0818e13b in ExecScan (node=0x8bccad8, accessMtd=0x819a810 <SeqNext>)
at execScan.c:143
#8 0x0819a809 in ExecSeqScan (node=0x8bccad8) at nodeSeqscan.c:130
#9 0x08186ead in ExecProcNode (node=0x8bccad8) at execProcnode.c:334
#10 0x0818610b in ExecutorRun (queryDesc=0x8bc99f4,
direction=ForwardScanDirection, count=0) at execMain.c:1233
#11 0x0822d824 in ProcessQuery (plan=0x8bb3fc8, params=<value optimized out>,
dest=0x8bb4044, completionTag=0xbfa23f7a "") at pquery.c:179
#12 0x0822dae8 in PortalRunMulti (portal=0x8bbd22c,
isTopLevel=<value optimized out>, dest=0x8bb4044, altdest=0x8bb4044,
---Type <return> to continue, or q <return> to quit---
completionTag=0xbfa23f7a "") at pquery.c:1242
#13 0x0822e2a4 in PortalRun (portal=0x8bbd22c, count=2147483647,
isTopLevel=1 '\001', dest=0x8bb4044, altdest=0x8bb4044,
completionTag=0xbfa23f7a "") at pquery.c:813
#14 0x08229363 in exec_simple_query (
query_string=0x8bb245c "UPDATE t SET geo
=\nconvert_from(decode('50696f74726bf3772c20506f6c616e64','hex'),
'LATIN2');") at postgres.c:963
#15 0x0822ae21 in PostgresMain (argc=4, argv=<value optimized out>,
username=0x8b31564 "pavel") at postgres.c:3535
#16 0x081f6ca8 in ServerLoop () at postmaster.c:3180
#17 0x081f7996 in PostmasterMain (argc=3, argv=0x8b2e528) at postmaster.c:1028
#18 0x081a99e0 in main (argc=3, argv=Cannot access memory at address 0x4
) at main.c:188

regards
Pavel Stehule

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Gilligan (#1)
Re: BUG #3866: Segfault during table update when using convert_from()

"Andrew Gilligan" <andy@tcpd.net> writes:

It seems there exists a bug in the way character set conversion
is handled in some circumstances.

Seems to be the bogus pfree() in pg_convert_from() that's causing
the problem :-(. Take that out and you should be OK.

Thanks for the report!

regards, tom lane

#4Andrew Gilligan
andy@tcpd.net
In reply to: Tom Lane (#3)
Re: BUG #3866: Segfault during table update when using convert_from()

On 9 Jan 2008, at 23:45, Tom Lane wrote:

"Andrew Gilligan" <andy@tcpd.net> writes:

It seems there exists a bug in the way character set conversion
is handled in some circumstances.

Seems to be the bogus pfree() in pg_convert_from() that's causing
the problem :-(. Take that out and you should be OK.

That's exactly it, thanks... Everything seems fine now.

The fix is trivial, so not sure if a patch is even warranted, but
I've attached the changes just in case.

Best regards,
-Andy

Attachments:

mbutils.diffapplication/octet-stream; name=mbutils.diff; x-unix-mode=0644Download+0-3