Thread

Commits

  1. ecpg: Fix zero-termination of string generated by intoasc()

  2. ecpg: Fix error handling on OOMs when parsing timestamps

  1. Returning non-terminated string in ECPG Informix-compatible function

    Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru> — 2024-01-29T08:47:31Z

    Greetings, everyone!
    
    While analyzing output of Svace static analyzer [1] I've found a bug.
    
    In function intoasc(interval * i, char *str) from file 
    src/interfaces/ecpg/compatlib/informix.c
    we return a non-terminated string since we use memcpy on tmp which is 
    itself NULL-teminated but
    last zero byte is not copied.
    
    The proposed solution is to use strcpy instead, since it is used in all 
    other functions in informix.c.
    
    The patch is attached.
    
    [1] - https://svace.pages.ispras.ru/svace-website/en/
    
    Oleg Tselebrovskiy, Postgres Pro
  2. Re: Returning non-terminated string in ECPG Informix-compatible function

    Ashutosh Bapat <ashutosh.bapat.oss@gmail.com> — 2024-01-30T07:12:37Z

    On Mon, Jan 29, 2024 at 2:17 PM <o.tselebrovskiy@postgrespro.ru> wrote:
    >
    > Greetings, everyone!
    >
    > While analyzing output of Svace static analyzer [1] I've found a bug.
    >
    > In function intoasc(interval * i, char *str) from file
    > src/interfaces/ecpg/compatlib/informix.c
    > we return a non-terminated string since we use memcpy on tmp which is
    > itself NULL-teminated but
    > last zero byte is not copied.
    >
    > The proposed solution is to use strcpy instead, since it is used in all
    > other functions in informix.c.
    >
    > The patch is attached.
    >
    > [1] - https://svace.pages.ispras.ru/svace-website/en/
    >
    
    Can you please add a test case showcasing the bug? I see dttoasc()
    uses strcpy(). So there's already a precedence.
    
    -- 
    Best Wishes,
    Ashutosh Bapat
    
    
    
    
  3. Re: Returning non-terminated string in ECPG Informix-compatible function

    Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru> — 2024-01-30T10:56:22Z

    Here's the code for bug reproduction:
    #include <stdio.h>
    #include <stdlib.h>
    
    EXEC SQL INCLUDE pgtypes_interval.h;
    EXEC SQL INCLUDE ecpg_informix.h;
    
    EXEC SQL BEGIN DECLARE SECTION;
    	char dirty_str[100] = "aaaaaaaaa_bbbbbbbb_ccccccccc_ddddddddd_";
    	interval *interval_ptr;
    EXEC SQL END DECLARE SECTION;
    
    int main()
    {
    	interval_ptr = (interval *) malloc(sizeof(interval));
    	interval_ptr->time = 100000000;
    	interval_ptr->month = 240;
    
    	printf("dirty_str contents before intoasc: %s\n", dirty_str);
    	intoasc(interval_ptr, dirty_str);
    	printf("dirty_str contents after intoasc: %s\n", dirty_str);
    	return 0;
    }
    
    And here's the output:
    
    dirty_str contents before intoasc: 
    aaaaaaaaa_bbbbbbbb_ccccccccc_ddddddddd_
    dirty_str contents after intoasc: @ 20 years 1 min 40 
    secscccc_ddddddddd_
    
    I compiled it with following commands (provided for quicker 
    reproduction):
    /path/to/pgsql/bin/ecpg informix_bug_example.pgc
    gcc -I/path/to/pgsql/include -c informix_bug_example.c
    gcc -o informix_bug_example informix_bug_example.o -L/path/to/pgsql/lib 
    -lecpg -lecpg_compat
    
    I've also found at least one project that uses intoasc() in it - 
    https://github.com/credativ/informix_fdw/
    
    Oleg Tselebrovskiy, Postgres Pro
    
    
    
    
  4. Re: Returning non-terminated string in ECPG Informix-compatible function

    Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru> — 2024-02-15T05:15:40Z

    Greetings again.
    I was looking through more static analyzer output and found another 
    problem.
    In ecpg/pgtypeslib/dt_common.c there are 4 calls of pgtypes_alloc.
    This function uses calloc and returns NULL if OOM, but we don't check 
    its
    return value and immediately pass it to strcpy, which could lead to 
    segfault.
    
    I suggest adding a check for a return value since all other calls of
    pgtypes_alloc are checked for NULL.
    
    A proposed patch (with previous and current changes) is attached
    
    Oleg Tselebrovskiy, Postgres Pro
  5. Re: Returning non-terminated string in ECPG Informix-compatible function

    Michael Paquier <michael@paquier.xyz> — 2024-02-15T05:25:07Z

    On Thu, Feb 15, 2024 at 12:15:40PM +0700, Oleg Tselebrovskiy wrote:
    > Greetings again.
    > I was looking through more static analyzer output and found another problem.
    > In ecpg/pgtypeslib/dt_common.c there are 4 calls of pgtypes_alloc.
    > This function uses calloc and returns NULL if OOM, but we don't check its
    > return value and immediately pass it to strcpy, which could lead to
    > segfault.
    >
    > I suggest adding a check for a return value since all other calls of
    > pgtypes_alloc are checked for NULL.
    
    Right.
    
    > @@ -654,7 +654,7 @@ intoasc(interval * i, char *str)
    >      if (!tmp)
    >          return -errno;
    >  
    > -    memcpy(str, tmp, strlen(tmp));
    > +    strcpy(str, tmp);
    
    For this stuff, Ashutosh's point was to integrate a test case in the
    patch.  With the pgc you have posted, most of the work is done, but
    this should be added to src/interfaces/ecpg/test/sql/ to add some
    automated coverage.  See the area for references showing how this is
    achieved.
    
    > @@ -2837,6 +2843,8 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d,
    >              case 'T':
    >                  pfmt++;
    >                  tmp = pgtypes_alloc(strlen("%H:%M:%S") + strlen(pstr) + 1);
    > +                if(!tmp)
    > +                    return 1;
    
    These are obviously wrong as pgtypes_alloc() could return NULL.
    --
    Michael
    
  6. Re: Returning non-terminated string in ECPG Informix-compatible function

    Oleg Tselebrovskiy <o.tselebrovskiy@postgrespro.ru> — 2024-02-15T10:17:17Z

    Thanks for review!
    
    I added a regression test that is based on code from previous email
    
    New patch is attached
    
    Oleg Tselebrovskiy, Postgres Pro
  7. Re: Returning non-terminated string in ECPG Informix-compatible function

    Michael Paquier <michael@paquier.xyz> — 2024-02-19T03:20:12Z

    On Thu, Feb 15, 2024 at 05:17:17PM +0700, Oleg Tselebrovskiy wrote:
    > Thanks for review!
    
    dt_common.c is quite amazing, the APIs that we have in it rely on
    strcpy() but we have no idea of the length of the buffer string given
    in input to store the result.  This would require breaking the
    existing APIs or inventing new ones to be able to plug some safer
    strlcpy() calls.  Not sure if it's really worth bothering.  For now,
    I've applied the OOM checks on HEAD and the fix with the null
    termination on all stable branches.
    --
    Michael