bugfindutils - Bugs: bug #25294, assertion failure on dangling...

 
 

bug #25294: assertion failure on dangling symlink to //

Submitter:  Eric Blake <ericb>
Submitted:  Sat 10 Jan 2009 11:44:14 PM UTC
   
 
Category:  find Severity:  3 - Normal
Item Group:  Wrong result Status:  Fixed
Privacy:  Public Assigned to:  ericb
Originator Name:  Eric Blake Open/Closed:  Closed
Release:  4.5.3 Fixed Release:  4.5.4
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sun 02 Aug 2009 03:06:21 PM UTC, comment #8: 

the version is 4.5.4

I'm sorry but I can't create a reproducible example but mine

What I've noted while trying was that it /seems/ to have something to do with disk cache (as it stops failing after a couple of times but it fails again if you echo 3 > /p/s/vm/drop_caches) AND that executing a similar script on /usr/lib/, executing ldd on a subset of .so, DID NOT fail, so that it could be related to the fact that, when my script runs, it modifies the files it matches (by vacuuming sqlite databases)
just speculations, though

federico fissore <federico>
Sun 02 Aug 2009 01:02:37 PM UTC, comment #7: 

federico, please indicate what version of find you are using.  Also, can you proproduce the problem with a script which creates a suitable example?  (I don't have your ~/.mozilla directory here!)



I'm suspicious of this part of the system call trace:

--- SIGCHLD (Child exited) @ 0 (0) ---
newfstatat(7, "cookies.sqlite-journal", 0x131ab00, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
lstat("cookies.sqlite-journal", 0x7fff7880b330) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/locale.alias", O_RDONLY) = 6


... because I'm not convinced that fd 7 corresponds to the working directory, so the lstat could fail or return the wrong information.

My guess is that the lstat call is inside symlink_loop() which is called at line 462 of ftsfind.c (i.e. for the FTS_NS case).

James Youngman <jay>
Group administrator
Wed 29 Jul 2009 10:27:44 AM UTC, comment #6: 

please check out the attachments
the bash script is the one that fails. the log is the strace log

federico fissore <federico>
Thu 16 Jul 2009 12:38:20 PM UTC, comment #5: 

Both examples now avoid assertion failures on cygwin with stock findutils 4.5.4, so I'm closing the report as fixed:

$ mkdir example
$ ln -s /nowhere example/n
$ find -L example
example
example/n
$ rm example/n
$ ln -s nowhere example/n
$ find -L example
example
example/n
$ rm example/n
$ ln -s loop example/loop
$ find -L example
example
find: `example/loop': Too many levels of symbolic links
$

Eric Blake <ericb>
Group administrator
Sat 07 Mar 2009 04:26:36 PM UTC, comment #4: 

Check-in b445af98c22cd2d13673e2699a77ab728a7073b0 changed this code a bit, as did 0b1acd3358466b02f32baf9423665113dc933492.

Is the problem still reproducible from the git master branch (currently at 89da37ea3b25fd7c95d831a6f319068c99c7406b)?

James Youngman <jay>
Group administrator
Sat 17 Jan 2009 07:22:35 PM UTC, comment #3: 

I would have expected ent->fts_info == FTS_SLNONE for the loop case.  That implies that the comment on line 472 could well be misleading.


I modified fts.c to always set d_type to DT_UNKNOWN but was not able to demonstrate a problem.

James Youngman <jay>
Group administrator
Sun 11 Jan 2009 03:31:59 AM UTC, comment #2: 

The assertion failure can also be reproduced with a loop:

$ mkdir example
$ ln -s loop example/loop
$ find -L example
example
find: `example/loop': Too many levels of symbolic links
assertion "state.type != 0" failed: file "ftsfind.c", line 475, function: consider_visiting
Aborted (core dumped)

As I see it, this only depends on having a system with d_type support, but on a file system where readdir returns DT_UNKNOWN on at least dangling symlinks.  Therefore, I think that it should be possible to find a file system under Linux that can reproduce this failure, rather than relying on the cygwin-specific behavior in stat'ing a dangling symlink to "//nowhere".

Eric Blake <ericb>
Group administrator
Sun 11 Jan 2009 01:58:54 AM UTC, comment #1: 

More info:

The bug first surfaced in commit acb82fe, Nov 30 2008, at the point when Jim provided a patch to gnulib fts to do fewer stat's when d_type is reliable.

The problem starts when readdir recognizes that it is too expensive to decide what the type of a broken symlink is (at least on cygwin), and returns DT_UNKNOWN (defined as 0).  Next, fts calls fts_stat, which fails because the symlink is broken, but on cygwin, a symlink to "//nowhere" fails with the nonstandard errno==ENOSHARE rather than the more typical ENOENT, so no lstat is attempted to see if the file might be a dangling symlink.

So the bug might be in fts.c, line 1540, for not recognizing all cases of bad symlinks (even ignoring cygwin's nonstandard ENOSHARE, what happens for a looping symlink that returns ELOOP?).  Would a readlink() be better than lstat() to determine that a symlink exists but can't be followed?

Eric Blake <ericb>
Group administrator
Sat 10 Jan 2009 11:44:14 PM UTC, original submission:  

On systems where d_type is valid, find is triggering an assertion (I'm not sure if this assertion also requires that // be distinct from /, in which case the assertion may be specific to cygwin 1.7, since earlier cygwin lack d_type and other systems don't have distinct //):

$ mkdir example
$ ln -s /nowhere example/n
$ find -L example
example
example/n

but the following asserts:

$ rm example/n
$ ln -s nowhere example/n
$ find -L example
example
assertion "state.type != 0" failed: file
"/usr/src/findutils-4.5.3-1/src/findutils-4.5.3/find/ftsfind.c", line 475,
function: consider_visiting
Aborted (core dumped)


Corinna Vinschen provided this analysis:

The assertion is basically

  if (ent->fts_info == FTS_NSOK || ent->fts_info == FTS_NS)
    assert (state.type != 0);

state.type is set in the calling function find() like this:

  while ( (ent=fts_read(p)) != NULL )
    {
      state.have_type = !!ent->fts_statp->st_mode;
      state.type = state.have_type ? ent->fts_statp->st_mode : 0;
    }

which is a bug, AFAICS.  The reason is that per the fts_read man page
the value of ent->fts_statp is undefined if ent->fts_info is FTS_NSOK
or FTS_NS.  So the values of state.have_type and consequentially
state.type are undefined as well and the above assertion makes no sense.

Eric Blake <ericb>
Group administrator

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #18490:  firefox.trace.log added by federico (62KiB - application/octet-stream - find 4.5.4 is still failing. disk cache seems to matter as, after a couple of runs, the script goes fine. but as you echo 3 > /proc/sys/vm/drop_caches it fails again)
file #18491:  vacuum_mozillas.sh added by federico (487B - application/x-sh - find 4.5.4 is still failing. disk cache seems to matter as, after a couple of runs, the script goes fine. but as you echo 3 > /proc/sys/vm/drop_caches it fails again)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by federico (Updated the item)
  • -email is unavailable- added by jay (Posted a comment)
  • -email is unavailable- added by ericb (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 7 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2009-07-29 federico Attached File- Added firefox.trace.log, #18490
        Attached File- Added vacuum_mozillas.sh, #18491
    2009-07-16 ericb StatusNeed Info Fixed
        Open/ClosedOpen Closed
        Fixed ReleaseNone 4.5.4
    2009-07-05 jay StatusNone Need Info
        Assigned toNone ericb

    Back to the top

    Powered by Savane 3.13-758e.
    Corresponding source code