develooper Front page | perl.perl5.porters | Postings from March 2008

Re: [perl #46173] possible fd bug in PerlIOStdio_close

Thread Previous | Thread Next
From:
Nicholas Clark
Date:
March 30, 2008 07:01
Subject:
Re: [perl #46173] possible fd bug in PerlIOStdio_close
Message ID:
20080330140135.GJ79799@plum.flirble.org
On Thu, Dec 20, 2007 at 06:42:49AM -0800, Steve Peters via RT wrote:
> On Sat Oct 06 05:12:48 2007, root@schmorp.de wrote:

> > While reading through perlio.c in current 5.8-devel, I found these
> >    lines
> > in PerlIOStdio_close:
> > 
> >    int dupfd = 0;
> >    ...
> >    dupfd = PerlLIO_dup(fd);
> >    ...
> >    if (dupfd) {
> > 
> > The dup won't be executed on any of my systems, but on those systems
> > where it is, it seems that if PerlLIO_dup returns 0, the code leaks a
> > filedescriptor. (Unless PerlLIO_dup does deep magic, but it seems to
> > simply call dup(), which returns 0 if that fd happens to be free.
> > 
> > just a fyi, really, I don't grok perlio :)

I don't think that anyone does, certainly no-one alive, but I'm not convinced
that Nick Ing-Simmons actually understood the interactions in it.

> This does look like a problem since 
> 
>     if (fd >= 0) {
> 
> is used elsewhere in the code.  I'll leave well enough alone for now,
> but I'll see if I can come up with an adequate test case.

I'm not sure that it's possible to make a viable test case, but independent
of this bug report I decided that it was wrong, and fixed it with change 33491.
(That code path is triggered on OS X)

Nicholas Clark

Change 33491 by nicholas@mouse-mill on 2008/03/12 11:46:17

	Correct logic error in PerlIOStdio_close() - 0 is an acceptable value
	from dup(), so it can't also be the "don't do anything later" value.

Affected files ...

... //depot/perl/perlio.c#382 edit

Differences ...

==== //depot/perl/perlio.c#382 (text) ====

@@ -3130,7 +3130,7 @@
 	int invalidate = 0;
 	IV result = 0;
 	int saveerr = 0;
-	int dupfd = 0;
+	int dupfd = -1;
 #ifdef SOCKS5_VERSION_NAME
     	/* Socks lib overrides close() but stdio isn't linked to
 	   that library (though we are) - so we must call close()
@@ -3171,7 +3171,7 @@
 	/* in SOCKS' case, let close() determine return value */
 	result = close(fd);
 #endif
-	if (dupfd) {
+	if (dupfd >= 0) {
 	    PerlLIO_dup2(dupfd,fd);
 	    PerlLIO_close(dupfd);
 	}

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About