Re: Found a buffer-overflow defect in asynchronous database connection API PQconnectPoll

Sudheer H R <sudheer.hr@tekenlight.com>

From: Sudheer H R <sudheer.hr@tekenlight.com>
To: pgsql-bugs@lists.postgresql.org
Date: 2021-06-23T12:40:57Z
Lists: pgsql-bugs
Further to this.

I tried a synchronous mode of connection, with the code below.

Even that produces the error report as below;

Sudheer


Source code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "libpq-fe.h"


int main()
{
    PGconn *p = NULL;
    const char* keywords[] = { "host", "dbname", "user", "password", NULL };
    const char* values[] = { "localhost", "AAA", "gen", "GEN", NULL };

    p = PQconnectdbParams(keywords, values, 0);

    if (p == NULL) {
        printf("COULD NOT ALLOCATE MEMORY\n");
        exit(1);
    }
    else if (PQstatus(p) == CONNECTION_BAD) {
        printf("COULD NOT CONNECT\n");
        PQfinish(p);
        p = NULL;
    }


    return 0;
}


makefile

all: a b

b.o: b.c
    cc -c -fsanitize="address" b.c -I/opt/local/include/postgresql13

a.o: a.c
    cc -c -fsanitize="address" a.c -I/opt/local/include/postgresql13

a: a.o
    cc -lpq -L/opt/local/lib/postgresql13/ -fsanitize="address" -o a a.o
    
b: b.o
    cc -lpq -L/opt/local/lib/postgresql13/ -fsanitize="address" -o b b.o

clean: 
    rm -f a a.o b b.o


REPORT:



=================================================================
==62688==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6070000173d6 at pc 0x0001049d68f4 bp 0x7ffeeb2a38a0 sp 0x7ffeeb2a3060
READ of size 71 at 0x6070000173d6 thread T0
    #0 0x1049d68f3 in wrap_strlen+0x183 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x198f3)
    #1 0x10498a7ea in dopr+0xe4 (libpq.5.dylib:x86_64+0x1c7ea)
    #2 0x10498a6e2 in pg_vsnprintf+0x52 (libpq.5.dylib:x86_64+0x1c6e2)
    #3 0x104982e91 in appendPQExpBufferVA+0x3e (libpq.5.dylib:x86_64+0x14e91)
    #4 0x104982fae in appendPQExpBuffer+0xc4 (libpq.5.dylib:x86_64+0x14fae)
    #5 0x104985b64 in pg_GSS_error_int+0x5b (libpq.5.dylib:x86_64+0x17b64)
    #6 0x104985af3 in pg_GSS_error+0x66 (libpq.5.dylib:x86_64+0x17af3)
    #7 0x1049864fe in pqsecure_open_gss+0x334 (libpq.5.dylib:x86_64+0x184fe)
    #8 0x10497440d in PQconnectPoll+0xac9 (libpq.5.dylib:x86_64+0x640d)
    #9 0x1049720f1 in connectDBComplete+0x11f (libpq.5.dylib:x86_64+0x40f1)
    #10 0x104971c61 in PQconnectdbParams+0x23 (libpq.5.dylib:x86_64+0x3c61)
    #11 0x10495da84 in main+0x3a4 (b:x86_64+0x100003a84)
    #12 0x7fff20563f5c in start+0x0 (libdyld.dylib:x86_64+0x15f5c)

0x6070000173d6 is located 0 bytes to the right of 70-byte region [0x607000017390,0x6070000173d6)
allocated by thread T0 here:
    #0 0x104a05460 in wrap_malloc+0xa0 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x48460)
    #1 0x7fff2d8f7396 in _gss_mg_get_error+0x96 (GSS:x86_64+0x9396)
    #2 0x7fff2d8f71e6 in gss_display_status+0x176 (GSS:x86_64+0x91e6)
    #3 0x104985b4b in pg_GSS_error_int+0x42 (libpq.5.dylib:x86_64+0x17b4b)
    #4 0x104985af3 in pg_GSS_error+0x66 (libpq.5.dylib:x86_64+0x17af3)
    #5 0x1049864fe in pqsecure_open_gss+0x334 (libpq.5.dylib:x86_64+0x184fe)
    #6 0x10497440d in PQconnectPoll+0xac9 (libpq.5.dylib:x86_64+0x640d)
    #7 0x1049720f1 in connectDBComplete+0x11f (libpq.5.dylib:x86_64+0x40f1)
    #8 0x104971c61 in PQconnectdbParams+0x23 (libpq.5.dylib:x86_64+0x3c61)
    #9 0x10495da84 in main+0x3a4 (b:x86_64+0x100003a84)
    #10 0x7fff20563f5c in start+0x0 (libdyld.dylib:x86_64+0x15f5c)

SUMMARY: AddressSanitizer: heap-buffer-overflow (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x198f3) in wrap_strlen+0x183
Shadow bytes around the buggy address:
  0x1c0e00002e20: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
  0x1c0e00002e30: fd fd fd fd fd fd fa fa fa fa fd fd fd fd fd fd
  0x1c0e00002e40: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x1c0e00002e50: fd fa fa fa fa fa fd fd fd fd fd fd fd fd fd fa
  0x1c0e00002e60: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fa fa
=>0x1c0e00002e70: fa fa 00 00 00 00 00 00 00 00[06]fa fa fa fa fa
  0x1c0e00002e80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0e00002e90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0e00002ea0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0e00002eb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x1c0e00002ec0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==62688==ABORTING
Abort



> On 23-Jun-2021, at 5:43 PM, Sudheer H R <sudheer.hr@tekenlight.com> wrote:
> 
> Hello,
> 
> I am trying to integrate the client library libpq with a server that is developed based on libev model on a Macbook PRO - maxOS Big Sur OSX version 11.4
> 
> While trying to sanitise the code for heap buffer overflows I compiled and linked the executable with clang -fsanitize=“address” option. The connection library indicates a buffer over flow in an internal source code of the module.
> 
> In order to isolate the problem, I tried writing a separate simple program as listed below, which also gives the same error report upon running.
> 
> 
> Request you to please provide any guidance in this regard.
> 
> 
> I am using the Mac ports based installation of PostgreSQL version 13.2 (or 3)
> 
> 
> Any help in this regard is much appreciated 
> 
> Regards,
> Sudheer
> 
> 
> 
> Source code:
> 
> 
> #include <unistd.h>
> #include "libpq-fe.h"
> 
> 
> int main()
> {
>     PGconn *p = NULL;
>     const char* keywords[] = { "host", "dbname", "user", "password", NULL };
>     const char* values[] = { "localhost", "AAA", "gen", "GEN", NULL };
> 
>     p = PQconnectStartParams(keywords, values, 0);
> 
>     if (p == NULL) {
>         printf("COULD NOT ALLOCATE MEMORY\n");
>         exit(1);
>     }
>     else if (PQstatus(p) == CONNECTION_BAD) {
>         printf("COULD NOT CONNECT\n");
>         PQfinish(p);
>         p = NULL;
>     }
> 
>     PostgresPollingStatusType ps;
> 
>     ps = PQconnectPoll(p);
>     while (ps != PGRES_POLLING_FAILED && ps != PGRES_POLLING_OK) {
>         sleep(1);
>         ps = PQconnectPoll(p);
>         printf("open_connection_finalize[%d]\n", ps);
>     }
> 
>     printf("DONE\n");
> 
>     return 0;
> }
> 
> 
> 
> 
> 
> BUFFER OVERFLOW SANITIZER REPORT
> 
> 
> open_connection_finalize[1]
> =================================================================
> ==62203==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60700001abd6 at pc 0x0001098118f4 bp 0x7ffee646d910 sp 0x7ffee646d0d0
> READ of size 71 at 0x60700001abd6 thread T0
>     #0 0x1098118f3 in wrap_strlen+0x183 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x198f3)
>     #1 0x1097c37ea in dopr+0xe4 (libpq.5.dylib:x86_64+0x1c7ea)
>     #2 0x1097c36e2 in pg_vsnprintf+0x52 (libpq.5.dylib:x86_64+0x1c6e2)
>     #3 0x1097bbe91 in appendPQExpBufferVA+0x3e (libpq.5.dylib:x86_64+0x14e91)
>     #4 0x1097bbfae in appendPQExpBuffer+0xc4 (libpq.5.dylib:x86_64+0x14fae)
>     #5 0x1097beb64 in pg_GSS_error_int+0x5b (libpq.5.dylib:x86_64+0x17b64)
>     #6 0x1097beaf3 in pg_GSS_error+0x66 (libpq.5.dylib:x86_64+0x17af3)
>     #7 0x1097bf4fe in pqsecure_open_gss+0x334 (libpq.5.dylib:x86_64+0x184fe)
>     #8 0x1097ad40d in PQconnectPoll+0xac9 (libpq.5.dylib:x86_64+0x640d)
>     #9 0x109793a2c in main+0x46c (a:x86_64+0x100003a2c)
>     #10 0x7fff20563f5c in start+0x0 (libdyld.dylib:x86_64+0x15f5c)
> 
> 0x60700001abd6 is located 0 bytes to the right of 70-byte region [0x60700001ab90,0x60700001abd6)
> allocated by thread T0 here:
>     #0 0x109840460 in wrap_malloc+0xa0 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x48460)
>     #1 0x7fff2d8f7396 in _gss_mg_get_error+0x96 (GSS:x86_64+0x9396)
>     #2 0x7fff2d8f71e6 in gss_display_status+0x176 (GSS:x86_64+0x91e6)
>     #3 0x1097beb4b in pg_GSS_error_int+0x42 (libpq.5.dylib:x86_64+0x17b4b)
>     #4 0x1097beaf3 in pg_GSS_error+0x66 (libpq.5.dylib:x86_64+0x17af3)
>     #5 0x1097bf4fe in pqsecure_open_gss+0x334 (libpq.5.dylib:x86_64+0x184fe)
>     #6 0x1097ad40d in PQconnectPoll+0xac9 (libpq.5.dylib:x86_64+0x640d)
>     #7 0x109793a2c in main+0x46c (a:x86_64+0x100003a2c)
>     #8 0x7fff20563f5c in start+0x0 (libdyld.dylib:x86_64+0x15f5c)
> 
> SUMMARY: AddressSanitizer: heap-buffer-overflow (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x198f3) in wrap_strlen+0x183
> Shadow bytes around the buggy address:
>   0x1c0e00003520: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
>   0x1c0e00003530: fd fd fd fd fd fd fa fa fa fa fd fd fd fd fd fd
>   0x1c0e00003540: fd fd fd fa fa fa fa fa fd fd fd fd fd fd fd fd
>   0x1c0e00003550: fd fa fa fa fa fa fd fd fd fd fd fd fd fd fd fa
>   0x1c0e00003560: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fa fa
> =>0x1c0e00003570: fa fa 00 00 00 00 00 00 00 00[06]fa fa fa fa fa
>   0x1c0e00003580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x1c0e00003590: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x1c0e000035a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x1c0e000035b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
>   0x1c0e000035c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
> Shadow byte legend (one shadow byte represents 8 application bytes):
>   Addressable:           00
>   Partially addressable: 01 02 03 04 05 06 07 
>   Heap left redzone:       fa
>   Freed heap region:       fd
>   Stack left redzone:      f1
>   Stack mid redzone:       f2
>   Stack right redzone:     f3
>   Stack after return:      f5
>   Stack use after scope:   f8
>   Global redzone:          f9
>   Global init order:       f6
>   Poisoned by user:        f7
>   Container overflow:      fc
>   Array cookie:            ac
>   Intra object redzone:    bb
>   ASan internal:           fe
>   Left alloca redzone:     ca
>   Right alloca redzone:    cb
>   Shadow gap:              cc
> ==62203==ABORTING
> Abort
> 
> 

Commits

  1. Don't assume GSSAPI result strings are null-terminated.