BUG #16200: returned data from ESQL/C FETCH is trampling outside assigned memory for CHAR column - Mailing list pgsql-bugs

From PG Bug reporting form
Subject BUG #16200: returned data from ESQL/C FETCH is trampling outside assigned memory for CHAR column
Date
Msg-id 16200-358624daecff6820@postgresql.org
Whole thread Raw
Responses Re: BUG #16200: returned data from ESQL/C FETCH is tramplingoutside assigned memory for CHAR column
List pgsql-bugs
The following bug has been logged on the website:

Bug reference:      16200
Logged by:          Matthias Apitz
Email address:      guru@unixarea.de
PostgreSQL version: 11.4
Operating system:   SuSE Linux SLES 12 SP4
Description:

We encounter the following problem with ESQL/C: Imagine a table with two
columns: CHAR(16) and DATE

In the database the CHAR column can contain not only 16 bytes, but 16
Unicode chars,
which are longer than 16 bytes if one or more of the chars is an UTF-8
multibyte
encoded char.

If one provides in C a host structure to FETCH the data as:

    EXEC SQL BEGIN DECLARE SECTION;
    struct  r_d02ben_ec {
        char    string[17];
        char    date[11];
    };
    typedef struct r_d02ben_ec t_d02ben_ec;
    t_d02ben_ec *hp_d02ben, hrec_d02ben;
    EXEC SQL END DECLARE SECTION;

and fetches the data with ESQL/C as:

    EXEC SQL FETCH hc_d02ben INTO :hrec_d02ben;

The generated C-code looks like this:

    ...
    ECPGdo(__LINE__, 0, 1, NULL, 0, ECPGst_normal, "fetch hc_d02ben",
ECPGt_EOIT,
        ECPGt_char,&(hrec_d02ben.string),(long)17,(long)1,sizeof( struct
r_d02ben_ec ),
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
        ECPGt_char,&(hrec_d02ben.date),(long)11,(long)1,sizeof( struct
r_d02ben_ec ),
        ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L,
        ...

As you can see for the first element CHAR the length 17 is given as argument
to ECPGdo()
together with the pointer to where the data should be stored
and for the second element DATE the length 11 is ggiven as argument (which
is big enough to
receive the ASCII string "MM.DD.YYYY" and a trailing \0).

What we now see using GDB is that for the first element all UTF-8 data
is returned, lets asume only one multibyte char, which gives 17 bytes,
not only 16, and the trailing NULL is already placed into the memory for
the DATE. Now the function ECPGdo() places the DATE as "MM.DD.YYYY"
into the area pointed to for the 2nd argument and with this overwrites
the NULL terminator of the string[17] element. Result is later a
SIGSEGV because the expected string in string[17] is not NULL
terminated anymore :-)

I would call it a bug, that ECPGdo() puts more than 17 bytes (16 bytes +
NULL) as return into the place pointed to by the host var pointer when
the column in the database has more (UTF-8) chars as will fit into
16+1 byte.


pgsql-bugs by date:

Previous
From: Michael Paquier
Date:
Subject: Re: Error while trying to open pgadmin
Next
From: PG Bug reporting form
Date:
Subject: BUG #16201: Second column in Range Partition is scanning all the partitions