Thread: Fwd: Bug#247306: odbc-postgresql: SIGSEGV with long inputs (> 10000 bytes)
Hi PostgreSQL developers! A week ago we at Debian received the bug report below: due to a buffer overflow in psqlodbc it is possible to crash (and possibly exploit) apache. I already sent this mail to the psqlodbc list [1], but unfortunately got no response so far. So maybe there are some hackers here who can help with this? I can reliably reproduce the error (using the small attached php4 script), but I do not know anything about the psqlodbc internals. I would be glad if someone could assist me with that. Thanks in advance and have a nice day! Martin [1] http://archives.postgresql.org/pgsql-odbc/2004-05/msg00006.php ----- Forwarded message from delman <delman@despammed.com> ----- Subject: Bug#247306: odbc-postgresql: SIGSEGV with long inputs (> 10000 bytes) Reply-To: delman <delman@despammed.com>, 247306@bugs.debian.org From: delman <delman@despammed.com> To: Debian Bug Tracking System <submit@bugs.debian.org> Date: Tue, 04 May 2004 15:25:24 +0200 X-Spam-Status: No, hits=0.0 required=4.0 tests=SUBJ_BRACKET_BALANCED, SUBJ_BRACKET_OFF,SUBJ_BRACKET_ON autolearn=no version=2.61 Package: odbc-postgresql Version: 1:07.03.0200-2 Severity: grave Tags: security Justification: user security hole I noticed Apache segfaulting when I feed a simple form with long inputs: [Tue May 4 11:32:10 2004] [notice] child pid 4084 exit signal Segmentation fault (11) Such inputs are used by php function odbc_connect as username and password to connect to a DSN using postgresql driver: $connection = @odbc_connect(DSN, $_POST['username'], $_POST['password']) The output of gdb is: (gdb) run -X -d apache [...] [Thread debugging using libthread_db enabled] [...] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 1076569920 (LWP 832)] 0x44c3d627 in SOCK_put_next_byte () from /usr/lib/postgresql/lib/psqlodbc.so Or: [same stuff here] 0x44c4c3d0 in strncpy_null () from /usr/lib/postgresql/lib/psqlodbc.so I suspect a security issue because playing around with long input strings of "A" I've been able to trigger in Apache error.logthis message: free(): invalid pointer 0x41414141! 0x41 is obviously one of my "A"... Other ODBC related messages found are: /usr/sbin/apache: relocation error: AAAA[...]AAA: symbol getDSNdefaults, version not defined in file with link time reference The SIGSEGV is triggered with input strings > 10000 bytes. I use Apache/1.3.29 (Debian GNU/Linux) PHP/4.3.4 mod_auth_pam/1.1.1mod_ssl/2.8.16 OpenSSL/0.9.7c -- System Information: Debian Release: testing/unstable APT prefers testing APT policy: (500, 'testing') Architecture: i386 (i686) Kernel: Linux 2.6.4 Locale: LANG=C, LC_CTYPE=C Versions of packages odbc-postgresql depends on: ii libc6 2.3.2.ds1-11 GNU C Library: Shared libraries an ii odbcinst1 2.2.4-9 Support library and helper program -- no debconf information ----- End forwarded message ----- -- Martin Pitt Debian GNU/Linux Developer martin@piware.de mpitt@debian.org http://www.piware.de http://www.debian.org
Attachment
Re: Fwd: Bug#247306: odbc-postgresql: SIGSEGV with long inputs (> 10000 bytes)
From
Peter Eisentraut
Date:
Martin Pitt wrote: > A week ago we at Debian received the bug report below: due to a > buffer overflow in psqlodbc it is possible to crash (and possibly > exploit) apache. I already sent this mail to the psqlodbc list [1], > but unfortunately got no response so far. So maybe there are some > hackers here who can help with this? The problem is that the ODBC driver just writes the long user name or password into its internal data structures without paying attention the fact that it's only got 256 bytes of space. (function PGAPI_Connect in file connection.c) It's the oldest bug in the book really.
Re: Fwd: Bug#247306: odbc-postgresql: SIGSEGV with long inputs (> 10000 bytes)
From
Martin Pitt
Date:
Hi! On 2004-05-12 1:31 +0200, Peter Eisentraut wrote: > Martin Pitt wrote: > > A week ago we at Debian received the bug report below: due to a > > buffer overflow in psqlodbc it is possible to crash (and possibly > > exploit) apache. I already sent this mail to the psqlodbc list [1], > > but unfortunately got no response so far. So maybe there are some > > hackers here who can help with this? > > The problem is that the ODBC driver just writes the long user name or > password into its internal data structures without paying attention the > fact that it's only got 256 bytes of space. (function PGAPI_Connect in > file connection.c) It's the oldest bug in the book really. Thanks for this hint and spotting the error, I think I see the problem now: PGAPI_Connect calls make_string(szDSN, cbDSN, ci->dsn); to copy the string (and similar with uid and password). ci->dsn is only MEDIUM_REGISTRY_LEN (256) bytes big, so if cbDSN >= 256, it will crash. So I suppose the function just has to check the cb* values, and if one of them is >= 256, return an appropriate error? Another possibility would be to add a fourth argument to make_string that specifies the size of the target buffer (and have it copy max(stringlen, bufferlen-1) bytes). This would force the correction of all places where make_string is used (just 13, so it should not get too hard). Any comments to that? Thanks, Martin -- Martin Pitt Debian GNU/Linux Developer martin@piware.de mpitt@debian.org http://www.piware.de http://www.debian.org
Re: Fix for buffer overflow ready [was: Fwd: Bug#247306: odbc-postgresql: SIGSEGV with long inputs (> 10000 bytes)]
From
Peter Eisentraut
Date:
Martin Pitt wrote: > The problem is that make_string() in misc.c does not check whether > the target buffer is big enough to hold the copied string. > > I added a bufsize parameter to make_string() and used it in all calls > to it. I tried it with my php4 crash test script and now it works > properly. Silently truncating various pieces of information is probably not the right thing. What are you truncating? If it's a query string you might open yourself up to SQL-injection type problems. Plus, the ODBC driver appears to have buffer overruns all over the place. We need to replace every instance of strcpy, strcat, sprintf, make_string, and the various other feeble attempts with pqexpbuffer from libpq. That's the only way to solve this problem once and for all.
Re: Fix for buffer overflow ready [was: Fwd: Bug#247306: odbc-postgresql: SIGSEGV with long inputs (> 10000 bytes)]
From
Martin Pitt
Date:
Hi! On 2004-05-13 19:43 +0200, Peter Eisentraut wrote: > Silently truncating various pieces of information is probably not the > right thing. But IMHO still better than overwriting arbitrary other data and code. If an user supplies bogus input, he cannot expect to get something sane out. > What are you truncating? By now: - DSN, username, password, and the whole connection string; - table names in info.c: make_string(szTableName, cbTableName, pktab, sizeof(pktab)); - Two calls in info.c: make_string(szPkTableName, cbPkTableName, pk_table_needed, sizeof(pk_table_needed)); make_string(szFkTableName, cbFkTableName, fk_table_needed, sizeof(fk_table_needed)); If these values should not be truncated, then psqlodbc should not use fixed buffer sizes. Currently truncating them is way more sane than letting them mess up the whole memory. > If it's a query string you might open yourself up to SQL-injection > type problems. I don't think that the patch affects whole query strings, but of course I may be wrong. The point of this patch was to fix the most apparent overflows with least possible changes, and after a week of silence on the lists I just had to do something about it. And now at least the connection and exec methods seem to work safely. > Plus, the ODBC driver appears to have buffer overruns all over the > place. We need to replace every instance of strcpy, strcat, sprintf, > make_string, and the various other feeble attempts with pqexpbuffer > from libpq. That's the only way to solve this problem once and for > all. I would be glad if the next psqlodbc version would be written in a sane way, without fixed string lengths and with a clear and safe string "class" interface. But doing this is far beyond the scope of a security patch (especially for Debian stable). One question: which mailing list is the better place to discuss this? -odbc or -bugs? Thanks and have a nice day! Martin -- Martin Pitt Debian GNU/Linux Developer martin@piware.de mpitt@debian.org http://www.piware.de http://www.debian.org
Fix for buffer overflow ready [was: Fwd: Bug#247306: odbc-postgresql: SIGSEGV with long inputs (> 10000 bytes)]
From
Martin Pitt
Date:
Hi again! Sorry for crossposting, but I sent the initial post also to -bugs, because I did not get an answer on -odbc. On 2004-05-11 12:03 +0200, Martin Pitt wrote: > I noticed Apache segfaulting when I feed a simple form with long inputs: > > [Tue May 4 11:32:10 2004] [notice] child pid 4084 exit signal Segmentation fault (11) > > Such inputs are used by php function odbc_connect as username and password to connect to a DSN using postgresql driver: > > $connection = @odbc_connect(DSN, $_POST['username'], $_POST['password']) > > The output of gdb is: > > (gdb) run -X -d apache > [...] > [Thread debugging using libthread_db enabled] > [...] > Program received signal SIGSEGV, Segmentation fault. > [Switching to Thread 1076569920 (LWP 832)] > 0x44c3d627 in SOCK_put_next_byte () from /usr/lib/postgresql/lib/psqlodbc.so > > Or: > [same stuff here] > 0x44c4c3d0 in strncpy_null () from /usr/lib/postgresql/lib/psqlodbc.so > > I suspect a security issue because playing around with long input strings of "A" I've been able to trigger in Apache error.logthis message: > > free(): invalid pointer 0x41414141! > > 0x41 is obviously one of my "A"... The problem is that make_string() in misc.c does not check whether the target buffer is big enough to hold the copied string. I added a bufsize parameter to make_string() and used it in all calls to it. I tried it with my php4 crash test script and now it works properly. The attached patch is for the current stable release 07.03.0200. Thanks a lot to Peter Eisentraut for pointing me at the problem origin. Unless you have a better idea it would be nice if you could apply the patch to the official sources and also include it in the next release. I will upload updated Debian packages for unstable and stable this afternoon (16:00 CEST) if nobody reports a problem or a better solution. Thanks in advance, Martin -- Martin Pitt Debian GNU/Linux Developer martin@piware.de mpitt@debian.org http://www.piware.de http://www.debian.org