pgsql-3866

Version:

8.3rc1

Bug Link:

http://www.postgresql.org/community/weeklynews/pwn20080113

http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/backend/utils/mb/mbutils.c?r1=1.68&r2=1.69

Symptom:

Segfault during table update when using convert_from()

Failure type:

Segment fault

Is there any log message?

Yes

How it is diagnosed:

We reproduced the failure.

How to reproduce:

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.
!>

Root Cause:

A bogus pfree of src_name

/*

 * Convert string using encoding_name. The destination

 * encoding is the DB encoding.

 *

 * TEXT convert_from(BYTEA string, NAME encoding_name) */

Datum

pg_convert_from(PG_FUNCTION_ARGS)

{

        Datum           string = PG_GETARG_DATUM(0);

        Datum           src_encoding_name = PG_GETARG_DATUM(1);

        Datum           dest_encoding_name = DirectFunctionCall1(namein,

                                                                        CStringGetDatum(DatabaseEncoding->name));

        Datum           result;

 

        result = DirectFunctionCall3(pg_convert, string,

                                                                 src_encoding_name, dest_encoding_name);

 -        pfree((void *) src_encoding_name);

        /*

         * pg_convert returns a bytea, which we in turn return as text, relying on

         * the fact that they are both in fact varlena types, and thus

         * structurally identical. Although not all bytea values are valid text,

         * in this case it will be because we've told pg_convert to return one

         * that is valid as text in the current database encoding.

         */

        PG_RETURN_TEXT_P(result);

}

Pattern of the failure:

Signal handler