GNU bug report logs - #10305
coreutils-8.14, "rm -r" fails with EBADF

Previous Next

Package: coreutils;

Reported by: "Joachim Schmitz" <jojo <at> schmitz-digital.de>

Date: Thu, 15 Dec 2011 14:08:01 UTC

Severity: wishlist

Tags: notabug

Full log


View this message in rfc822 format

From: "Joachim Schmitz" <jojo <at> schmitz-digital.de>
To: "'Paul Eggert'" <eggert <at> cs.ucla.edu>
Cc: 10305 <at> debbugs.gnu.org, bug-gnulib <at> gnu.org
Subject: bug#10305: coreutils-8.14, "rm -r" fails with EBADF
Date: Wed, 21 Dec 2011 15:15:04 +0100
> From: Paul Eggert [mailto:eggert <at> cs.ucla.edu]
> Sent: Monday, December 19, 2011 6:29 PM
> To: Joachim Schmitz
> Cc: 10305 <at> debbugs.gnu.org; bug-gnulib <at> gnu.org
> Subject: Re: bug#10305: coreutils-8.14, "rm -r" fails with EBADF
> 
> On 12/19/11 00:11, Joachim Schmitz wrote:
> > So it [opendirat] 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 [fdopendir_with_dup] calls close(3) !!!
> 
> Yes, that's what I'd expect.  fdopendir_with_dup sees that fd is 3 and dupfd is 4.
> So it invokes close (3) and then fd_clone_opendir (4, ...) because it wants
> fd_clone_opendir to open a file (getting fd 3) and then operate on fd 3.
> 
> then close(4) (the fd from the dup())  errno set to ENOTSUP
> 
> Sorry, you've jumped ahead too fast for me to follow.  As I understand it,
> fd_clone_opendir (4, ...) should first try openat_proc_name (..., 4, "."), which
> should fail; 

Yes, it does (try and fail)

> it should then try _gl_directory_name (4), and this should return the
> name "D" of the directory.  

It does.

> fd_clone_opendir should then invoke opendir ("D"),
> which should then open the directory, 

it does
> internally get file descriptor 3, and then
> return a nonnull DIR * pointer that is based on file descriptor 3; this is the value
> that fd_clone_opendir should return back to fdopendir_with_dup.

It calls dirfd() with that DIR *, that calls  DIR_TO_FD(), which return -1 and sets errno to ENOTSUP
Then dirfd() get called again and fails again.
close (3), calls fs_clone_opendir() and as dupfd is 4 but older_dupfd is -1, it calls close(4) and sets errno to ENTOSUP (from save_errno)
 
> So when fdopendir_with_dup later does that close(4), it should be OK.
> since the directory is still open on file descriptor 3.

As I see it we now have fds 3 and 4 closed.

> When you say that errno is set to ENOTSUP, though, that suggests that my
> analysis is wrong and fd_clone_opendir returns NULL with errno == ENOTSUP.
> Can you please investigate why that might be?

Ah, should have read to the end first... OK back a couple steps...

Hmm DIR_TO_FD() is :
#define DIR_TO_FD(Dir_p) -1

In config.h:
/* the name of the file descriptor member of DIR */
/* #undef DIR_FD_MEMBER_NAME */

#ifdef DIR_FD_MEMBER_NAME
# define DIR_TO_FD(Dir_p) ((Dir_p)->DIR_FD_MEMBER_NAME)
#else
# define DIR_TO_FD(Dir_p) -1
#endif

So fd_clone_dir() does not return NULL, but has errno set to ENTOSUP.


Our "struct DIR" has  2 shorts and one long, with funny names dd1, dd2 and dd3... looking at their content: nothing looks like a proper fd (values 7, 257 and 135067072, respectively)


Where to go now?

Resorting to wild guesses, I tried all 3 members of struct DIR as DIF_FD_MEMBER_NAME, no change to the EBADF





This bug report was last modified 12 years and 110 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.