Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAKHv7phZGhF5D-o8Z98pe0JG+UEWgq=HwRGPdS-WhHoX1-0ijg@mail.gmail.com>
Date: Wed, 24 Oct 2012 23:22:13 +0200
From: Paul Schutte <sjpschutte@...il.com>
To: musl@...ts.openwall.com
Subject: Re: Possible file stream bug

Hi,

It is not my code, but I can not see why it is invalid.

Here is a strace when linked agains glibc:

close(1)                                = 0
open("/dev/tty", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1
fstat(1, {st_mode=S_IFCHR|0666, st_rdev=makedev(5, 0), ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo
...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0x7f6eb782e000
write(1, "test this\n", 10)             = 10
exit_group(0)                           = ?

Here is an strace aganst musl:

close(1)                                = 0
open("/dev/tty", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 1
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo
...}) = 0
dup2(1, 1)                              = 1
close(1)                                = 0
writev(1, [{"test this", 9}, {"\n", 1}], 2) = -1 EBADF (Bad file descriptor)
exit_group(0)                           = ?

Musl is doing a dup2 and then closes the old descriptor. In this case, it
is the same and therefore the stream is closed.
One could possibly test for the case where newfd==oldfd and not close oldfd
in that case. Or am I missing something ?

Regards
Paul

On Wed, Oct 24, 2012 at 10:59 PM, Rich Felker <dalias@...ifal.cx> wrote:

> On Wed, Oct 24, 2012 at 09:36:28PM +0200, Paul Schutte wrote:
> > Hi
> >
> > I compiled and linked libwebserver-0.5.3 against musl.
> >
> > It would just strangely break halfway through a request. After hours of
> > searching, I found the problem.
> >
> > I can demonstrate it with the following code:
> >
> > #include <unistd.h>
> > #include <stdio.h>
> >
> > int main() {
> >     FILE *fstream;
> >
> >     fclose(stdout);
> >
> >     fstream=freopen("/dev/tty","w",stdout);
> >
> >     if (fstream==NULL) {
> >         fprintf(stderr,"freopen failed\n");
> >     }
> >
> >     printf("test this\n");
> >
> >
> >     return 0;
> > }
> >
> > This snippet works fine when using glibc.
>
> This code is invalid; you have invoked undefined behavior by accessing
> stdout (passing it to freopen) after it was closed with fclose. Remove
> the fclose and it works correctly. This code would certainly cause
> memory corruption and/or crash if it were used on any FILE other than
> one of the 3 builtin ones (since the memory would have been returned
> to the heap when fclose was called) so there is no sense in trying to
> support this invalid usage. You should file a bug report with the
> application.
>
> Rich
>

Content of type "text/html" skipped

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.