[Top][All Lists]

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

Re: fopen()-pclose() bug in install-info

From: Barath Aron
Subject: Re: fopen()-pclose() bug in install-info
Date: Tue, 9 Feb 2021 21:10:28 +0100

On 2/9/21 6:11 PM, Gavin Smith wrote:
On Fri, Jan 29, 2021 at 01:41:22PM +0100, Barath Aron wrote:

I ran into a bug in the "install-info" program, where the "dir" file is
opened with fopen(), and it was closed with pclose(). That's why
"install-info" hangs on the OS I use.
The path in the code is clear.

910: f = open_possibly_compressed_file (...)
700: f = fopen (*opened_filename, FOPEN_RBIN);
# this might be executed, but won't make any difference
882: f = freopen (*opened_filename, "r", f);
888: return f;
939: pclose(f);

I was able to get this work with the attached patch file, based on the
comments and the code around it.
I didn't completely follow the problem and your fix.  When exactly does
install-info hang and what OS do you use?

I think your fix stops pclose being called using the condition that
f != stdin in the readfile function but it doesn't look like the right
place for this.

Relevant commits in the git history are 2d03d088d9 and 3c795d1bcf
and this message


The code path I wrote is the trace of the program, I didn't made it up. It first opened a regular, non-compressed file with fopen() [this was in line 700], then it would freopen()ed [line 882, but it won't make any difference], then closed the fopen()ed file with pclose() [line 939]. And per-definition, you can't pclose() a FILE opened with fopen(). It is undefined behavior, libc is "allowed" to wait for something which will not happen. POSIX spec says: "If the argument stream to pclose() is not a pointer to a stream created by popen(), the result of pclose() is undefined." So, on Linux and on some other OSs this case works by mistake, but it is not required.

My patch is just a messy workaround to get rid of the problem (closing a fopen()ed file with pclose()). Yes, my intention was clearly to stop pclose() being called. If you take a look at the code, the only path where pclose() is not called is when it was a regular, non-compressed file.

I use Threos OS, which is a Unix-like system, which is currently under development. It's libc is based on musl, but the Linux-specific stuff was reimplemented.


reply via email to

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