bugfindutils - Bugs: bug #60207, -prune returns false for files for...

 
 

bug #60207: -prune returns false for files for which fstatat() fails with EACCESS

Submitted by:  Stephane Chazelas <stephanechazelas>
Submitted on:  Wed 10 Mar 2021 12:17:47 PM UTC  
 
Category:  find Severity:  3 - Normal
Item Group:  Wrong result Status:  None
Privacy:  Public Assigned to:  None
Originator Name:  Open/Closed:  Open
Release:  4.7.0 Fixed Release:  None

Add a New Comment (Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

Wed 10 Mar 2021 07:04:29 PM UTC, comment #3: 

comment #2:
[...]

> In parser.c, we see that -prune adds it unless -depth is set:

[...]

> And indeed, adding -depth doesn't yield the extra "[call stat] [need type]".

[...]

Note that in any case, -prune can't be used (is ineffective) with -depth (as expected, documented and specified by POSIX).

Stephane Chazelas <stephanechazelas>
Wed 10 Mar 2021 02:26:21 PM UTC, comment #2: 

Thanks for the report.

Hmm, with '-D tree' we can see that -prune inserts a "[call stat] [need type]".

$ find -D tree -name 'a*' -prune -o -print 2>&1 | sed -n '/^Optimized command line/{n; s/ .est success rate [0-9.]*.//g; p}'
( -name a* -a [call stat] [need type] -prune  ) -o -print

In parser.c, we see that -prune adds it unless -depth is set:

  if (options.do_dir_first == false)
    our_pred->need_stat = our_pred->need_type = false;

And indeed, adding -depth doesn't yield the extra "[call stat] [need type]".

find -D tree -depth -name 'a*' -prune -o -print 2>&1 | sed -n '/^Optimized command line/{n; s/ .est success rate [0-9.]*.//g; p}'
(  ( -depth -a -name a*  ) -a -prune  ) -o -print

The condition has been added in commit
https://git.sv.gnu.org/cgit/findutils.git/commit/?id=d62aacb1b

The question is why?  It seems that this because -prune uses S_ISDIR()
stop at the current level ... have to investigate.

Bernhard Voelker <berny>
Project Administrator
Wed 10 Mar 2021 12:27:27 PM UTC, comment #1: 

For the record, comparison with other find implementations on that second (symlink-based) example on the same system:

$ gnu-find -L . -name 'a*' -prune -o -print
.
./b1
find: ‘./a1’: Permission denied
./a1
./b2
find: ‘./a5’: Not a directory
find: ‘./a4’: Too many levels of symbolic links
$ busybox find -L . -name 'a*' -prune -o -print
.
./b1
find: ./a1: Permission denied
./b2
find: ./a5: Not a directory
find: ./a4: Too many levels of symbolic links
$ sfind -L . -name 'a*' -prune -o -print
.
./b1
./b2
$ heirloom-find -L . -name 'a*' -prune -o -print
.
./b1
heirloom-find: cannot follow symbolic link ./a3: No such file or directory
heirloom-find: cannot follow symbolic link ./a1: Permission denied
./b2
heirloom-find: cannot follow symbolic link ./a5: Not a directory
heirloom-find: cannot follow symbolic link ./a4: Too many levels of symbolic links

(heirloom-find being the one from the "heirloom toolchest" based on OpenSolaris, and sfind being from schily-tools).

See also these differences wrt to which files are reported without -prune:

$ find -L . -name 'a*'
./a3
find: ‘./a1’: Permission denied
./a1
find: ‘./a5’: Not a directory
./a5
find: ‘./a4’: Too many levels of symbolic links
./a2
$ busybox find -L . -name 'a*'
./a3
find: ./a1: Permission denied
find: ./a5: Not a directory
find: ./a4: Too many levels of symbolic links
./a2
$ sfind -L . -name 'a*'
./a3
./a1
./a5
./a4
./a2
$ heirloom-find -L . -name 'a*'
heirloom-find: cannot follow symbolic link ./a3: No such file or directory
heirloom-find: cannot follow symbolic link ./a1: Permission denied
heirloom-find: cannot follow symbolic link ./a5: Not a directory
heirloom-find: cannot follow symbolic link ./a4: Too many levels of symbolic links
./a2

Stephane Chazelas <stephanechazelas>
Wed 10 Mar 2021 12:17:47 PM UTC, original submission:  

(initially from https://unix.stackexchange.com/questions/638372/why-does-find-still-try-to-access-gvfs-and-even-includes-it-in-the-output-de by DJCrashdummy user there).

Reproduced with GNU find 4.8.0 and current git head (v4.8.0-5-gcaa03867) built with default options on Debian GNU/Linux testing amd64.

Reproducer:

$ mkdir testdir; cd testdir
$ touch a1 a2 b1 b2
$ sudo bindfs --no-allow-other . a1
$ ls -l
ls: cannot access 'a1': Permission denied
total 0
-????????? ? ?        ?        ?            ? a1
-rw-r--r-- 1 stephane stephane 0 Mar 10 11:53 a2
-rw-r--r-- 1 stephane stephane 0 Mar 10 11:53 b1
-rw-r--r-- 1 stephane stephane 0 Mar 10 11:53 b2
$ find . -name 'a*' -prune -o -print
.
./b1
find: ‘./a1’: Permission denied
./a1
./b2

See how "./a1" was output even though it matches "a*".

Here using bindfs as a different user as a way to have a file (a1) that is not lstat()able. The OP had the problem initially with a .gvfs directory (also a fuse FS mount point).

It can also be reproduced with -L/-follow and symlinks to inaccessible areas:

$ mkdir testdir; cd testdir
$ touch a2 b1 b2
$ ln -s /var/spool/cron/crontabs/foo a1
$ ln -s /no/such/file a3
$ ln -s a4 a4
$ ln -s a2/foo a5
$ find -L . -name 'a*' -prune -o -print
.
./b1
find: ‘./a1’: Permission denied
./a1
./b2
find: ‘./a5’: Not a directory
find: ‘./a4’: Too many levels of symbolic links

See how a1 was reported (for which stat() fails with EACCESS), but not  a3 (ENOENT), a4 (ELOOP), a5 (ENOTDIR).

Stephane Chazelas <stephanechazelas>

 

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

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by berny (Posted a comment)
  • -email is unavailable- added by stephanechazelas (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.

     

     

     

    No changes have been made to this item

    Back to the top


    Powered by Savane 3.6