bugfindutils - Bugs: bug #14619, find -perm +... broken in 4.2.25

 
 

bug #14619: find -perm +... broken in 4.2.25

Submitter:  Andreas Metzler <ametzler>
Submitted:  Thu 22 Sep 2005 06:08:09 PM UTC
   
 
Category:  find Severity:  3 - Normal
Item Group:  Wrong result Status:  Fixed
Privacy:  Public Assigned to:  jay
Originator Name:  Open/Closed:  Closed
Release:  4.2.25 Fixed Release:  4.2.27
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Sat 19 Nov 2005 10:32:22 PM UTC, comment #15: 

I have applied an edited form of this patch to the current development code (since I already had some changes in the developement code and I went a bit fiurther in trying to be clear).

James Youngman <jay>
Group administrator
Mon 14 Nov 2005 06:18:51 PM UTC, comment #14: 

Jay wrote in comment #13

> Andreas, did you intend both patch files to be applied, or
> just one of them?


Just the newer one (find.diff), it is a superset of the first one (perm.diff).
            cu andreas

Andreas Metzler <ametzler>
Fri 11 Nov 2005 07:04:29 AM UTC, comment #13: 

Andreas, did you intend both patch files to be applied, or just one of them?

(I also must figure out where the upstream perm.texi file comes from)

James Youngman <jay>
Group administrator
Sat 15 Oct 2005 12:22:28 PM UTC, comment #12: 

Updated patch, including the example suggested in comment #8 is attached.
        cu andreas


Andreas Metzler <ametzler>
Sat 15 Oct 2005 11:38:07 AM UTC, comment #11: 

Eric wrote:
-----------

> However, if it is desired, find could treat mode "x" as an
> extension to POSIX, as equivalent to "+x", so that -perm /x could
> be shorthand for -perm /+x.

-----------

I would prefer if this special exemption was not added. Even old versions of GNU find do not accept x as valid mode:

ametzler@argenau:~$ ~/FIND/find-4.1.20 /tmp/ -perm x
/home/ametzler/FIND/find-4.1.20: invalid mode `x'
ametzler@argenau:~$ ~/FIND/find-4.1.20 /tmp/ -perm +x
/home/ametzler/FIND/find-4.1.20: invalid mode `+x'

            cu andreas

Andreas Metzler <ametzler>
Sun 09 Oct 2005 02:38:49 PM UTC, comment #10: 

You had a slight typo in comment #9 - with umask 0022, the mode "+r" evaluates as 0200 (or perhaps you meant umask 0002, to get 0220), from the point of view of chmod.  But your doc patch looked nice.

See my note 1 at the end of comment #3.  POSIX has an ambiguity on whether the mode bits of -perm obey umask on + and - and ignore it on =, or whether it ignores umask for all three of +, -, and =.  I believe findutils' current behavior of ignoring umask in all three cases is probably okay, but it is probably worth a question to the austin group to see if our interpretation is correct.  I note also that in Solaris 8, find obeyed the umask (although there were other places where -perm was non-POSIX compliant, so it is not really the best comparison point).  I don't have access to Solaris 10 or any other implementation of find that claims to be compliant, for comparison purposes.

Also, I realized that I was slightly mistaken in comment #3 - "x" is not a valid mode ('x' is only valid when proceeded with an op), so -perm +x in the older versions of find should not have worked, and -perm /x does not work now.  However, if it is desired, find could treat mode "x" as an extension to POSIX, as equivalent to "+x", so that -perm /x could be shorthand for -perm /+x.

Eric Blake <ericb>
Group administrator
Sun 09 Oct 2005 09:07:54 AM UTC, comment #9: 

Hello,
I've attached a minor documention update, giving a suggestion why -perm -+x works. I'd appreciate review.

Eric, find's -perm seems to ignore umask:

With umask 0022 the mode "+r" evaluates as 0220:
------------
ametzler@argenau:/tmp$ LC_ALL=C chmod -v +w 0000
mode of `0000' changed to 0220 (-w--w----)
------------

however GNU find ignores umask and evaluates '+w' as '0222':
--------------
ametzler@argenau:/tmp$ find findtest/ -perm +w -printf '%m\n'
222
--------------

Is this a bug?
              cu andreas

Andreas Metzler <ametzler>
Sat 08 Oct 2005 01:36:50 PM UTC, comment #8: 

Might I suggest the following documentation approach for the man and info pages:

-perm mode: exact match of set and unset bits in symbolic or numeric mode; includes symbolic modes with leading '+' but not with leading '-'

-perm -mode: match all set bits (and ignore other bits) in symbolic or numeric mode

-perm /mode: match any set bits (and ignore other bits) in symbolic or numeric mode

-perm +mode: match any set bits (and ignore other bits) in numeric mode (use /mode for symbolic)

Then include an example showing how to find a file that has all three read bits, at least one write bit, and no execute bits, in both numeric and symbolic representation:

find . -perm -444 -perm +222 \! -perm /111
find . -perm -a+r -perm /a+w \! -perm /a+x

Eric Blake <ericb>
Group administrator
Sat 08 Oct 2005 08:30:40 AM UTC, comment #7: 

Jay wrote:

> Andreas, do you have any further thoughts on this?


No, I don't. I am grateful that Eric has taken the time to explain what kind of strings POSIX accepts, which was my main problem.

I am going to close the respective Debian bug with pointers to documentation and a warning in NEWS.Debian.

> do you have any thoughts on how we can improve the documentation > to explain things better


If I have, I'll come up with a patch. ;-)
           thanks, cu andreas

Andreas Metzler <ametzler>
Sat 08 Oct 2005 06:31:32 AM UTC, comment #6: 

I've moved the other issue that Eroc discovered to bug #14748.

Andreas, do you have any further thoughts on this?   If you still believe it's a bug I'll refer to the POSIX documentation and try to figure out a way forward.  However, if in any case you're also happy that this is not a software bug, do you have any thoughts on how we can improve the documentation to explain things better?

James Youngman <jay>
Group administrator
Thu 06 Oct 2005 03:55:36 PM UTC, comment #5: 

$ touch 000 100 111 777
$ for f in * ; do touch $f $f ; done
                  ^^^^^
Obviously, that should be a chmod.

Eric Blake <ericb>
Group administrator
Thu 06 Oct 2005 03:49:07 PM UTC, comment #4: 

I don't think the original poster has discovered any bugs, rather just their misunderstanding of the (admittedly confusing) POSIX requirements.  I have, however, found a bug in 4.2.25:

$ touch 000 100 111 777
$ for f in * ; do touch $f $f ; done
$ find . -perm --x
.
./000
./100
./111
./777
$ find . -perm +-x
./000
$ find . -perm /-x
$

The first two are correct.  --x means use mode "-x", which maps to the template 0000, and find all files that have all set bits in the template set on the file (no bits meet this criteria), without regard to the state of any bit cleared in the template (ie, every file should match).  +-x means use mode "+-x", which maps to the template 0000, and do an exact match (only ./000 has all permissions cleared).

However, /-x means use mode "-x", and find all files that have any set bit in the template set on the file (no bits meet this criteria), without regard to the state of any bit cleared in the template (ie, every file should match).  So the bug is that /-x should behave like --x, but did not.

Eric Blake <ericb>
Group administrator
Thu 06 Oct 2005 02:54:35 PM UTC, comment #3: 

The POSIX rules are that -perm mode only returns true on files that exactly match mode, if mode is a valid POSIX mode without a leading -; and the POSIX grammar for valid modes includes leading +.  The old findutils behavior were often incompatible with POSIX (find ignored the leading plus, then parsed the remaining mode, then returned true if any of the specified bits in the remaining mode were set on a file).  The new behavior is that the leading plus is part of the mode, then find returns true only on an EXACT match.

The POSIX rules are found in http://www.opengroup.org/onlinepubs/009695399/utilities/find.html and http://www.opengroup.org/onlinepubs/009695399/utilities/chmod.html

Now, for your example: the old behavior of -perm +x is to treat mode as "x", which maps to 0111, then return true if any of the three execute bits are set on the file without regard to the read or write bits.  This is now provided by -perm /x.  The new behavior of -perm +x is to treat mode as "+x", which maps to 0111 & ~umask during chmod, but which maps to 0111 & 07777 in find [see note 1 below], then to return true on files that are EXACTLY that mode (ie a file that has NO read or write permissions, but all three execute permissions).  Some modes, like "+x", are extremely rare in file systems, explaining why your output has dramatically decreased.

Another example: -perm +u+x used to be (and -perm /u+x still should be) treated as the mode "u+x", which maps to 0100, then returning true for ALL files that have the u+x bit set regardless of the state of their other bits.  Now, per POSIX, +u+x is treated as the valid mode "+u+x" (which is identical to "+u,+x", and again maps to 0111 & 07777).

The only case where the 4.2.25 behavior is retained is where the mode given to perm is not a valid POSIX mode, but when stripping the leading plus, a valid mode results.  An example of this would be -perm +a+x.  "+a+x" is not a valid mode, but "a+x" is, and maps to 0111.  So, findutils invokes the old behavior of selecting all files that have any one of their three execute bits set, regardless of the state of the read or write bits.

Unfortunately, the grammar for modes permitted by POSIX state that a leading + can be followed by: , + - = u g o r w x X s t.  The ONLY character that can appear in a valid mode but which cannot directly follow '+' is 'a'.  So in terms of backwards compatibility, EVERY symbolic mode, except for those starting with a leading 'a', are affected by the change in findutils semantics to be POSIX compliant, from the old behavior of returning true if any bit in the specified mode is set regardless of unspecified bits, to the new behavior of returning true if there is an exact match (all bits specified, and no other bits, are set).  Thus, you should get used to -perm /mode instead of -perm +mode.

[note 1] One of the POSIX requirements is ambiguous when read in English - it states: "An op symbol of '+' shall set the appropriate mode bits in the template; '-' shall clear the appropriate bits; '=' shall set the appropriate mode bits, without regard to the contents of process' file mode creation mask."  One parse is roughly "('+' shall set); ('-' shall clear); ('=' shall set, and ignore umask)",  the other parse is roughly "('+' shall set; '-' shall clear; '=' shall set), all while ignoring umask".  But it looks like findutils 4.2.25 chose the second parse (ignore the umask for all three ops, and not just =), as evidenced by this trace:

$ touch 100 111
$ chmod 100 100
$ chmod 111 111
$ umask 011
$ find . -perm +x
./111
$

If the umask mattered, then +x maps to 0111 & ~umask, which would then find only ./100.  But since findutils is ignoring umask, then +x maps to 0111 & 07777, which finds only ./111.

Eric Blake <ericb>
Group administrator
Mon 03 Oct 2005 11:08:36 PM UTC, comment #2: 

Does -perm /... do what you expected -perm +... to do?

James Youngman <jay>
Group administrator
Sat 24 Sep 2005 05:00:23 PM UTC, comment #1: 

Hello,
Afaict almost any usage of -perm +'symbolic mode' is broken in .25.
(Checked e.g. u+x g=w u+w,g+r).

Contrary to my initial claim 4.2.(21-24) is not ok, though, -perm +<smbolic mode> has lots of false positives, e.g -perm +u+x matches  455, 472, 621 and 417. (Afaict it matches everything with any execute bit set.)

cu andreas

Andreas Metzler <ametzler>
Thu 22 Sep 2005 06:08:09 PM UTC, original submission:  

Hello,

this is a copy of http://bugs.debian.org/329358 reported by Ph. Marek:
--------------
# find /usr/bin/ -type f -perm +x
# ls -la /usr/bin/ | head -6
insgesamt 215060
drwxr-xr-x   2 root   root      94208 2005-09-21 07:59 .
drwxr-xr-x  14 root   root       4096 2005-07-20 10:14 ..
-rwxr-xr-x   1 root   root      23368 2005-09-04 03:32 [
-rwxr-xr-x   1 root   root       5644 2005-09-04 23:04 411toppm
-rwxr-xr-x   1 root   root         39 2005-08-11 01:52 7z
# find /usr/bin/ -type f | wc
   2183    2183   41277
# find /usr/bin/ -type f -perm +o+x | wc
      0       0       0

4.2.24-1 was ok.
---------------

I have verified that 4.2.24 indeed seems to work, this breakage is new.

thanks, cu andreas



Andreas Metzler <ametzler>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #2900:  find.diff added by ametzler (5KiB - text/plain - updated documentation patch)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by ametzler (Originator Email)
  •  

    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 8 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2005-12-06 jay Open/ClosedOpen Closed
        Fixed ReleaseNone 4.2.27
    2005-11-19 jay StatusNone Fixed
        Assigned toNone jay
    2005-11-15 jay Attached File#3034 Removed
    2005-10-15 ametzler Attached File- Added find.diff, #3043
    2005-10-09 ametzler Attached File- Added perm.diff, #3034
    2005-09-22 ametzler Carbon-Copy- Added -email is unavailable-

    Back to the top

    Powered by Savane 3.14-d582.
    Corresponding source code