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

 
 

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

Submitter:  Stephane Chazelas <stephanechazelas>
Submitted:  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
* Mandatory Fields

Add a New Comment Rich Markup
   

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>
Group 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)
  •  

    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.

     

    No changes have been made to this item

    Back to the top

    Powered by Savane 3.13-f8d8.
    Corresponding source code