bin/59167: Wide-character string formatting functions overrun
internal buffer
Aristarkh A Zagorodnikov
xm-freebsd at x-infinity.com
Mon Nov 10 23:50:27 PST 2003
>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 at 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:
More information about the freebsd-bugs
mailing list