Date: Tue, 11 Nov 2003 10:49:18 +0300 (MSK) From: Aristarkh A Zagorodnikov <xm-freebsd@x-infinity.com> To: FreeBSD-gnats-submit@FreeBSD.org Subject: bin/59167: Wide-character string formatting functions overrun internal buffer Message-ID: <200311110749.hAB7nIxw097037@brain.cc.rsu.ru> Resent-Message-ID: <200311110750.hAB7oNWe057407@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 59167 >Category: bin >Synopsis: Wide-character string formatting functions overrun internal buffer >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Mon Nov 10 23:50:23 PST 2003 >Closed-Date: >Last-Modified: >Originator: Aristarkh A Zagorodnikov >Release: FreeBSD 5.1-CURRENT i386 >Organization: X-Infinity Software >Environment: System: FreeBSD brain.cc.rsu.ru 5.1-CURRENT FreeBSD 5.1-CURRENT #0: Mon Sep 22 16:20:31 MSD 2003 os@brain.cc.rsu.ru:/usr/obj/usr/src/sys/brain.athlon-xp.HEAD.2003-09-23 i386 >Description: The problem manifests itself in wide-character string formatting functions (namely swprintf/vswprintf). Consider the target buffer of arbitrary size (for simplicity let it be large enough to contain entire output). When swprintf or vswprintf prints to this buffer, it fails inside the __vfwprintf function or shortly afterwards if output exceeds 128 characters. This is due to overflow of internal FILE buffer which seems to never get reallocated in wide-character string formatting functions. P.S. this problem seems to exist on other BSD-based systems - I first occured it in Darwin 7.0 (MacOS X 10.3) >How-To-Repeat: The following is a near-minimal example of swprintf failure. $ cat swprintf-fail.c #include <stdio.h> #include <wchar.h> int main(int argc, char* argv) { wchar_t buffer[200]; swprintf(buffer, 199, L"01234568901234568901234568901234568901234568901234568901234568901234568901234568901234568901234568901234568901234568901234568901"); return 0; } $ gcc swprintf-fail.c -g3 -O0 $ ./a.out Bus error (core dumped) >Fix: Note that the following conclusions are made after only a brief looking at the problem code so they may be partially or event completely wrong. The fix involves support for __SSTR and __SALC FILE flags in output function which is called from internal formatting function __vfwprintf. Currently, __vfwprintf uses __fputwc for output, which in turn uses __sputc which blindly writes characters and calls __swbuf when buffer is exhausted. In contrast, single-character internal formatting function __vfprintf uses __sfvwrite function to write output, which correctly handles __SSTR and __SALC FILE flags (reallocating the buffer) and does not exhibit the problem. So, proposed solutions are: 1. rewrite __vfwprintf output to use something other than __fputwc (i.e. use __sfvwrite with some wcs->mbcs preprocessing?) 2. fix __fputwc to support the __SSTR and __SALC flags (bad idea, this function should be fast) 3. fix __swbuf to support the __SSTR and __SALC flags (looks good to me, especially because it's called at the exact time when buffer is about to overflow) I already concluded a quick patch using (3), but not tested it good enough, so I'm not posting it here. If someone considers that my patch can be of any value, I will gladly submit it for review. >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200311110749.hAB7nIxw097037>