[Top][All Lists]

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

bug#10305: coreutils-8.14, "rm -r" fails with EBADF

From: Joachim Schmitz
Subject: bug#10305: coreutils-8.14, "rm -r" fails with EBADF
Date: Mon, 19 Dec 2011 09:11:39 +0100

> From: Paul Eggert [mailto:address@hidden
> Sent: Sunday, December 18, 2011 11:24 PM
> To: Joachim Schmitz
> Cc: address@hidden; address@hidden
> Subject: Re: bug#10305: coreutils-8.14, "rm -r" fails with EBADF
> On 12/18/11 02:31, Joachim Schmitz wrote:
> > it seems to go wrong in fcntl.c, line 194:
> >
> >             /* Haiku alpha 2 loses fd flags on original.  */
> >             int flags = fcntl (fd, F_GETFD);    <==
> >             if (flags < 0)
> >               {
> >                 result = -1;
> >                 break;
> >               }
> >
> > that fcntl() returns a -1 with errno set to EBADF.
> What is the value of fd at that point?


> Is it actually an invalid file descriptor?

Not sure, and wouldn't know how to tell, it certainly looks valid but 
apparenlty fcntl() thinks otherwise.
It was my suspicion but I couldn't find it.
But see further down...
> > For some reason I can step into that fcntl(), guess it is calling the 
> > system's
> fcntl here?
> Yes, that's how it's supposed to work.

OK, I thought so, but weren't sure.

> If you plant a breakpoint on the parent fts_build, and single step through 
> that,
> can you find out whether continue_readdir is true?

No it is not

>  If it's true, then please
> investigate why dirfd (fts.c line 1285) returned an invalid file descriptor.  
> If it's
> false, then please investigate why opendirat (..., &dir_fd) (fts.c line 1301)
> succeeded but set dir_fd to an invalid file descriptor.

OK, attention, lengthy...:
opendirat() calls openat_safer() which calls openat() which calls 
openat_permissive() which call rpl_open() which calls orig_open() which calls 
open() (which succeeds and returns 3) and _gl_register_fd() (which does nothing 
suspicious to the fd) and finally feeds that into fd_safer(). That does nothing 
but checking whther fd is not between STDIN and STDERR (which it is not). 
Everything looks fine so far, to me anyway.
Back in opendirat() and into set_cloexec_flag(), which calls 
rpl_fcntl(F_GETFD)= which calls the real fcntl() and successful. It calls it 
again with F_SETFD, this too seems successful.
So it goes into fdopendir(), fdopendir_with_dup(), rpl_dup(), the real dup() 
(disguised as dup_nothrow(), with success), _gl_register_dup(), nothing but 
success, no suspicious activity against fd.

Then it calls close(3) !!! then close(4) (the fd from the dup())  errno set to 

Back in fts_build() calling dup_safer(3) (which should be invalid meanwhile, as 
it got closed above!) rpl_fcntl(), calling the real fcntl() with errno EBADF 
and errors out.

So in fdopendir_with_dup() the fd gets closed and hence made invalid?!?

Bye, Jojo

reply via email to

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