bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: undefined behavior in closeout, aggravated by libsigsegv


From: Eric Blake
Subject: Re: undefined behavior in closeout, aggravated by libsigsegv
Date: Sat, 18 Jul 2009 05:38:38 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.22) Gecko/20090605 Thunderbird/2.0.0.22 Mnenhy/0.7.6.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Bruno Haible on 7/18/2009 1:03 AM:
>> calls close_stream (stdout)
>> => fclose (stdout)
>> detects that pending data was lost, so call error()
>> => fflush (stdout)
>>
>> According to POSIX, using stdout after it has been passed to fclose is 
>> undefined behavior.
> 
> Yup. We did not detect this bug earlier because on most systems, fflush
> returns -1/EBADF in this situation, rather than crashing.

Actually, it returns 0 without setting errno on Linux.  And on Solaris, it
returns 0 but set errno to EBADF.

I think the point that POSIX was trying to make is that _most_ streams are
dynamically allocated (via fopen or fdopen), and therefore using them
after fclose() is triggering the undefined behavior inherent with using
freed memory.  But the three std streams are pre-allocated, even though
they may start life already mapped to a closed stream.  Maybe it's worth
asking the Austin group whether the standard streams should be granted
exceptional status and given a guarantee to still portably work in other
API (well, fail with EBADF)?

> 
>> What's the best way to do that?  Have 
>> close_stdout call freopen("/dev/null","w",stdout) prior to calling error()?
> 
> Yes, this looks like the right fix to me. With "/dev/null" being replaced with
> DEV_NULL defined as in lib/pipe.h, for mingw portability.
> 
>> Convince the glibc folks to change error() to not call fflush(stdout) if 
>> fileno
>> (stdout) is closed?
> 
> This would not help: After fclose (stdout), "any use of stdout results in
> undefined behavior", says POSIX, hence fileno (stdout) is already undefined
> behaviour.

Ah, but fileno(stdout) == 1 by definition of STDOUT_FILENO, so you don't
have to go via fileno (you can directly use fcntl(1,...) to learn whether
the fd has been closed).

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkphtD4ACgkQ84KuGfSFAYAtlACfab5JvzsM54uZ4nwYU8c4Dz4d
MHYAni+kW0ICj/o9Uf/nhAE/1ivMuliT
=g/qd
-----END PGP SIGNATURE-----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]