Bug 456888 - fflush on wide-oriented stream segfaults in some locale
fflush on wide-oriented stream segfaults in some locale
Status: CLOSED NOTABUG
Product: Fedora
Classification: Fedora
Component: glibc (Show other bugs)
9
i686 Linux
low Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
Fedora Extras Quality Assurance
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2008-07-28 09:48 EDT by Watanabe, Yuki
Modified: 2008-07-29 12:38 EDT (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2008-07-29 12:38:00 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
the core dump of the test case (300.00 KB, application/octet-stream)
2008-07-28 09:48 EDT, Watanabe, Yuki
no flags Details

  None (edit)
Description Watanabe, Yuki 2008-07-28 09:48:27 EDT
Description of problem:
The "fflush" function seems to involve an invalid memory use.
If it is called with a wide-character oriented stream as the argument,
it may result in a segmentation fault or an infinite loop.
This occurs when the stream is open for reading a regular file (not
a terminal or a pipe).
The gdb debugger says that the stack is corrupted when I interrupt the
program in the infinite loop.

Version-Release number of selected component (if applicable):
reproducible with glibc-2.8-8 (i686) on fedora 9

How reproducible:
always, at least on the condition described below.
The behavior differs depending on the locale and the input text.

Steps to Reproduce:
$ cat flushbug.c
#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wchar.h>
#include <locale.h>

int main(void)
{
	wchar_t buf[1000];

	setlocale(LC_ALL, "");
	fgetws(buf, 1000, stdin);
	fflush(stdin);
	execlp("cat", "cat", (const char *) NULL);
	return 1;
}
$ cat flushbug.txt.en 
foo
bar
baz
$ gcc -std=c99 -ggdb -o flushbug flushbug.c
$ LC_ALL=C ./flushbug <flushbug.txt.en 
bar
baz
$ LC_ALL=ja_JP.utf8 ./flushbug <flushbug.txt.en 
Segmentation fault (core dumped)
  
Actual/Expected results:
The output of "LC_ALL=C ./flushbug <flushbug.txt.en" is the desired result.
The first line of the input file is consumed by the "flushbug" program and
the remaining lines are read and output by "cat".
A call to "fflush" is required to ensure that the input file is re-seeked
so that the "cat" program reads the second and following lines.
Without "fflush", more than one lines might be consumed by the buffering in
the "flushbug" program.

The test case works well in some locales and does not in others.
Locales that work includes C, en_US.iso88591, de_DE.iso885915@euro.
Locales that does not work includes en_US.utf8, de_DE.utf8, ja_JP.eucjp.

Additional info:
The core dump of the test case above is attached.
Comment 1 Watanabe, Yuki 2008-07-28 09:48:27 EDT
Created attachment 312777 [details]
the core dump of the test case
Comment 2 Ulrich Drepper 2008-07-29 03:01:33 EDT
The test program writes an uninitialized data region.  That's of course not
valid and a crash is a perfectly fine response.  Provide a correct program which
shows problems.
Comment 3 Watanabe, Yuki 2008-07-29 03:39:00 EDT
(In reply to comment #2)
Do you mean we need something like "wmemset(buf, 0, 1000)" before calling wgetws?
The program is reading from stdin by wgetws, not writing, so we do not have to initialize
the buffer, I believe.
Comment 4 Ulrich Drepper 2008-07-29 12:38:00 EDT
I misread the program.  Indeed, you don't have to clear the memory.

But now I can tell you that the program is outright wrong.  fflush is not
defined on input stream.

Note You need to log in before you can comment on or make changes to this bug.