From dev@26th.net  Tue Dec 20 14:54:19 2005
Return-Path: <dev@26th.net>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 3631816A41F
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 20 Dec 2005 14:54:19 +0000 (GMT)
	(envelope-from dev@26th.net)
Received: from 26th.net (26th.net [217.79.183.16])
	by mx1.FreeBSD.org (Postfix) with ESMTP id B1AE243D49
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 20 Dec 2005 14:54:18 +0000 (GMT)
	(envelope-from dev@26th.net)
Received: by 26th.net (Postfix, from userid 1001)
	id 1B52D1DA14; Tue, 20 Dec 2005 15:54:17 +0100 (CET)
Message-Id: <20051220145417.1B52D1DA14@26th.net>
Date: Tue, 20 Dec 2005 15:54:17 +0100 (CET)
From: Anatoli Klassen <anatoli@aksoft.net>
Reply-To: Anatoli Klassen <anatoli@aksoft.net>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] side effect of -delete option of find(1) 
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         90687
>Category:       bin
>Synopsis:       [patch] side effect of -delete option of find(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    avg
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Dec 20 15:00:12 GMT 2005
>Closed-Date:    Mon Jan 18 15:39:54 UTC 2010
>Last-Modified:  Mon Jan 18 15:39:54 UTC 2010
>Originator:     Anatoli Klassen
>Release:        FreeBSD 5.4-RELEASE-p6 i386
>Organization:
>Environment:
System: FreeBSD mercury.26th.net 5.4-RELEASE-p6 FreeBSD 5.4-RELEASE-p6 #0: Wed Jul 27 12:58:07 CEST 2005 root@mercury.26th.net:/usr/obj/usr/src/sys/MERCURY i386

>Description:
	If -delete option is used it cancel -L option silently.
	So find does something different as it does with just -print option.
	The result could be deleting of all symbolic links instead of broken ones only even
	if user has already validated this with previous -print run.

>How-To-Repeat:
	Create a file, symbolic link to it and a broken symbolic link:
	touch a && ln -s a b && ln -s c d

	Now detect all broken links:
	find -L . -type l
	- works fine, shows that "d" is broken.

	Then try to delete the broken links
	find -L . -type l -delete
	- all links are deleted, not only broken ones.

>Fix:

A patch to remove the side effect. It does not allow to delete the broken links because
there is once more check in the code with comment "sanity check", but at least it will
show error message and not delete correct links.

--- /usr/src/usr.bin/find/function.c	Thu Jul 29 05:33:55 2004
+++ find/function.c	Tue Dec 20 14:16:56 2005
@@ -453,8 +453,6 @@
 {
 
 	ftsoptions &= ~FTS_NOSTAT;	/* no optimise */
-	ftsoptions |= FTS_PHYSICAL;	/* disable -follow */
-	ftsoptions &= ~FTS_LOGICAL;	/* disable -follow */
 	isoutput = 1;			/* possible output */
 	isdepth = 1;			/* -depth implied */
 
To delete the links really one can use "find -L . -type l -print0 | xargs -0 rm"

>Release-Note:
>Audit-Trail:

From: Parv <parv@pair.com>
To: Anatoli Klassen <anatoli@aksoft.net>
Cc: FreeBSD-gnats-submit@FreeBSD.org
Subject: Re: bin/90687: [patch] side effect of -delete option of find(1)
Date: Tue, 20 Dec 2005 18:29:42 -0500

 in message <20051220145417.1B52D1DA14@26th.net>,
 wrote Anatoli Klassen thusly...
 >
 > 
 > >Environment:
 > System: FreeBSD mercury.26th.net 5.4-RELEASE-p6 FreeBSD 5.4-RELEASE-p6 #0: Wed Jul 27 12:58:07 CEST 2005 root@mercury.26th.net:/usr/obj/usr/src/sys/MERCURY i386
 > 
 > >Description:
 > If -delete option is used it cancel -L option silently.  So find does
 > something different as it does with just -print option.  The result could be
 > deleting of all symbolic links instead of broken ones only even if user has
 > already validated this with previous -print run.
 > 
 > >How-To-Repeat:
 > Create a file, symbolic link to it and a broken symbolic link:
 > touch a && ln -s a b && ln -s c d
 > 
 > Now detect all broken links:
 > find -L . -type l
 > - works fine, shows that "d" is broken.
 > 
 > Then try to delete the broken links
 > find -L . -type l -delete
 > - all links are deleted, not only broken ones.
 
 In your example above ...
 
   - "b" & "d" are found due to "-type l" criteria,
   - information about "a" is returned, instead of "b", due to "-L"
     option
   - file information about "a" is suppressed as it is not a link,
   - information about "d" is returned as it is a link and and the
     linked file does not exist.
   - in the end, all you have is "d" in the output.
 
 
 Refer to "-L" option description ...
 
   -L      Cause the file information and file type (see stat(2))
           returned for each symbolic link to be those of the file
           referenced by the link, not the link itself.  If the
           referenced file does not exist, the file information and
           type will be for the link itself.
 
 
   - Parv
 
 -- 
 

From: "Anatoli Klassen" <anatoli@aksoft.net>
To: FreeBSD-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: bin/90687: [patch] side effect of -delete option of find(1)
Date: Wed, 21 Dec 2005 10:34:26 +0100 (CET)

 > In your example above ...
 >
 >   - "b" & "d" are found due to "-type l" criteria,
 >   - information about "a" is returned, instead of "b", due to "-L"
 >     option
 >   - file information about "a" is suppressed as it is not a link,
 >   - information about "d" is returned as it is a link and and the
 >     linked file does not exist.
 >   - in the end, all you have is "d" in the output.
 
 Exactly. But not try to add the -delete option - both "b" and "d" will be
 deleted, not only "d".
 
 

From: David Taylor <davidt@yadt.co.uk>
To: Anatoli Klassen <anatoli@aksoft.net>
Cc: FreeBSD-gnats-submit@FreeBSD.org
Subject: Re: bin/90687: [patch] side effect of -delete option of find(1)
Date: Thu, 22 Dec 2005 23:49:02 +0000

 On Tue, 20 Dec 2005, Anatoli Klassen wrote:
 > 
 > >How-To-Repeat:
 > 	Create a file, symbolic link to it and a broken symbolic link:
 > 	touch a && ln -s a b && ln -s c d
 > 
 > 	Now detect all broken links:
 > 	find -L . -type l
 > 	- works fine, shows that "d" is broken.
 > 
 > 	Then try to delete the broken links
 > 	find -L . -type l -delete
 > 	- all links are deleted, not only broken ones.
 
 I'm also seeing this problem, and I just noticed that this is
 given as an example in the find(1) manpage:
 
 EXAMPLES
 ..
      find -L /usr/ports/packages -type l -delete
              Delete all broken symbolic links in /usr/ports/packages.
 ..
 
 -- 
 David Taylor

From: Nikos Ntarmos <ntarmos@ceid.upatras.gr>
To: bug-followup@freebsd.org, anatoli@aksoft.net
Cc:  
Subject: Re: bin/90687: [patch] side effect of -delete option of find(1)
Date: Tue, 4 Sep 2007 06:06:16 +0300

 I just stumbled upon this issue while reading the manpage for find(1).
 IMHO the fact that -delete turns -follow off is a good thing, so I
 consider this more of a bug in the manpage. The included patch removes
 the erroneous example and adds a word or two about -delete not honoring
 -L. There is a mention of -delete not interacting well with options that
 alter the traversal algorithm, but that is somewhat vague in this case.
 
 --- find.1.diff begins here ---
 Index: find.1
 ===================================================================
 RCS file: /opt/freebsd/cvs/src/usr.bin/find/find.1,v
 retrieving revision 1.82
 diff -u -r1.82 find.1
 --- find.1	28 Feb 2007 10:19:25 -0000	1.82
 +++ find.1	4 Sep 2007 02:56:40 -0000
 @@ -306,6 +306,24 @@
  .Dq Pa \&.
  for security reasons.
  Depth-first traversal processing is implied by this option.
 +Moreover, beware that
 +.Ic -delete
 +does
 +.Ar not
 +honor the semantics of
 +.Ic -L
 +since it turns off following of symbolic links for security reasons.
 +Thus,
 +.Pp
 +.Dl "find -L /usr/ports/packages -type l -delete"
 +.Pp
 +would delete
 +.Ar all
 +symbolic links under
 +.Ar /usr/ports/packages
 +as if
 +.Ic -L
 +had not been defined in the command line at all.
  .It Ic -depth
  Always true;
  same as the
 @@ -843,9 +861,6 @@
  Use the
  .Xr echo 1
  command to print out a list of all the files.
 -.It Li "find -L /usr/ports/packages -type l -delete"
 -Delete all broken symbolic links in
 -.Pa /usr/ports/packages .
  .It Li "find /usr/src -name CVS -prune -o -depth +6 -print"
  Find files and directories that are at least seven levels deep
  in the working directory
 ---- find.1.diff ends here ----

From: Romain =?iso-8859-1?Q?Tarti=E8re?= <romain@blogreen.org>
To: bug-followup@FreeBSD.org, anatoli@aksoft.net
Cc:  
Subject: Re: bin/90687: [patch] side effect of -delete option of find(1)
Date: Sun, 21 Oct 2007 20:08:49 +0200

 --n8g4imXOkfNTN/H1
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 The find manpage says:
 > The find utility recursively descends the directory tree for each
 > _pathname_ listed, evaluating an _expression_ (composed of the
 > ``primaries'' and ``operands'' listed below) in terms of each file in
 > the tree.
 
 Most operands return True or False depending on the nature of a found
 file (i.e. -nouser: True if the file belongs to an unknown user), other
 performs actions (i.e -print: This primary always evaluates to true.  It
 prints the pathname of the current file to standard output).
 
 The -delete operand also return true all the time.  In other word, as
 -print or -delete are just two operands that return true, we can expect
 an expression using the first or the second act on the same files,
 displaying filenames for the first case, and deleting files for the
 second.
 
 
 According to me, silently disabling symbolic links following depending
 on witch operands are set looks odd.  In fact, if I am not sure of what
 I am doing, I may first run find with a -print operand, and if
 everything is okay, then replace -print with -delete.  It is exactly
 what I did after reading the man page example regarding the "Delete all
 broken symbolic links in /usr/ports/packages".  I got 2-3 broken links
 as a result and so confidently replaced -print by -delete to actually do
 the job. I basically see all this as a ``for'' loop that behaves
 differently depending on what is performed in the without-side-effects
 loop block.
 
 Moreover, 1.8 revision (introduction of the -delete operand) commit
 message states that "the code is extremely paranoid", consider race
 condition, etc.  But the behaviour of find is to not traverse symbolic
 links if not told otherwise.  In other word, it will have the same
 behaviour as rm: considering symbolic links, not referenced files, and
 does not fills the requirements for a symbolic link race condition. So
 maybe the tool may be less paranoid and only the paranoidness of the
 user may be taken into account?
 
 Without the restriction told about here, find would be a good tool to
 delete particular files according to random criteria (and then the
 -delete operand makes sense).
 
 
 At least, if for ``security reasons'' we don't want the user to use -L
 and -delete at the same time, we'd better raise an error and do nothing:
 "find: -L and -delete cannot be used simultaneously"
 ... or even sort of a -shoot-me-in-the-foot option to force find to do
 ``risky'' stuff rather than doing something the user probably doesn't
 wants.
 
 
 BTW, for those who reached the PR page after deleting a brunch of
 symlinks in /usr/ports/packages, you can resurrect them with:
 
 # for PORT in `pkg_info -q -a -o`; do cd /usr/ports/$PORT && \
                                       make package-links; done
 
 
 Romain
 
 --n8g4imXOkfNTN/H1
 Content-Type: application/pgp-signature
 Content-Disposition: inline
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.4 (FreeBSD)
 
 iD8DBQFHG5Wx2OmjP/9W/0MRAqWnAJ9en87vwKJ/cWFbNArLOm3rBkwY/wCfemb2
 Q+fpZAYLuqnCydfS199ThfI=
 =He+u
 -----END PGP SIGNATURE-----
 
 --n8g4imXOkfNTN/H1--

From: Andriy Gapon <avg@icyb.net.ua>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/90687: [patch] side effect of -delete option of find(1)
Date: Thu, 08 Jan 2009 18:24:27 +0200

 I can still reproduce this issue with 7.1.
 I think that this is the most dangerous unexpected behavior that I have
 encountered using FreeBSD so far!
 
 -- 
 Andriy Gapon

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/90687: commit references a PR
Date: Tue, 19 May 2009 14:24:06 +0000 (UTC)

 Author: avg
 Date: Tue May 19 14:23:54 2009
 New Revision: 192381
 URL: http://svn.freebsd.org/changeset/base/192381
 
 Log:
   find: do not silently disable -L when -delete is used
   
   First of all, current behavior is not documented and confusing,
   and it can be very dangerous in the following sequence:
   find -L . -type l
   find -L . -type l -delete
   (the second line is even suggested by find(1)).
   
   Instead simply refuse to proceed when -L and -delete are both used.
   A descriptive error message is provided.
   The following command can be safely used to remove broken links:
   find -L . -type l -print0 | xargs rm -0
   
   To do:		update find(1)
   PR:		bin/90687
   Obtained from:	Anatoli Klassen <anatoli@aksoft.net>
   Approved by:	jhb (mentor)
 
 Modified:
   head/usr.bin/find/function.c
 
 Modified: head/usr.bin/find/function.c
 ==============================================================================
 --- head/usr.bin/find/function.c	Tue May 19 14:10:14 2009	(r192380)
 +++ head/usr.bin/find/function.c	Tue May 19 14:23:54 2009	(r192381)
 @@ -427,11 +427,13 @@ f_delete(PLAN *plan __unused, FTSENT *en
  
  	/* sanity check */
  	if (isdepth == 0 ||			/* depth off */
 -	    (ftsoptions & FTS_NOSTAT) ||	/* not stat()ing */
 -	    !(ftsoptions & FTS_PHYSICAL) ||	/* physical off */
 -	    (ftsoptions & FTS_LOGICAL))		/* or finally, logical on */
 +	    (ftsoptions & FTS_NOSTAT))		/* not stat()ing */
  		errx(1, "-delete: insecure options got turned on");
  
 +	if (!(ftsoptions & FTS_PHYSICAL) ||	/* physical off */
 +	    (ftsoptions & FTS_LOGICAL))		/* or finally, logical on */
 +		errx(1, "-delete: forbidden when symlinks are followed");
 +
  	/* Potentially unsafe - do not accept relative paths whatsoever */
  	if (strchr(entry->fts_accpath, '/') != NULL)
  		errx(1, "-delete: %s: relative path potentially not safe",
 @@ -462,8 +464,6 @@ c_delete(OPTION *option, char ***argvp _
  {
  
  	ftsoptions &= ~FTS_NOSTAT;	/* no optimise */
 -	ftsoptions |= FTS_PHYSICAL;	/* disable -follow */
 -	ftsoptions &= ~FTS_LOGICAL;	/* disable -follow */
  	isoutput = 1;			/* possible output */
  	isdepth = 1;			/* -depth implied */
  
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
Responsible-Changed-From-To: freebsd-bugs->avg 
Responsible-Changed-By: brian 
Responsible-Changed-When: Sun Jun 14 06:54:42 UTC 2009 
Responsible-Changed-Why:  
Work is in-progress by avg (r192381) 

http://www.freebsd.org/cgi/query-pr.cgi?pr=90687 
Responsible-Changed-From-To: avg->jilles 
Responsible-Changed-By: ed 
Responsible-Changed-When: Fri Sep 18 13:40:56 UTC 2009 
Responsible-Changed-Why:  
Jilles, you'd better have this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=90687 
Responsible-Changed-From-To: jilles->avg 
Responsible-Changed-By: ed 
Responsible-Changed-When: Fri Sep 18 13:47:24 UTC 2009 
Responsible-Changed-Why:  
This is my first day helping out sorting bugs. Looks like I've got a lot 
to learn. This patch has already been taken care of by avg. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=90687 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/90687: commit references a PR
Date: Sun, 20 Sep 2009 16:48:10 +0000 (UTC)

 Author: jilles
 Date: Sun Sep 20 16:47:56 2009
 New Revision: 197363
 URL: http://svn.freebsd.org/changeset/base/197363
 
 Log:
   Update find(1) man page for -L/-delete interaction.
   
   It is a bit unfortunate that the example to delete broken symlinks now uses
   rm(1), but allowing this with -delete would require fixing fts(3) to not
   imply FTS_NOCHDIR if FTS_LOGICAL is given (or hacks in the -delete option).
   
   PR:		bin/90687
   MFC after:	2 weeks
 
 Modified:
   head/usr.bin/find/find.1
 
 Modified: head/usr.bin/find/find.1
 ==============================================================================
 --- head/usr.bin/find/find.1	Sun Sep 20 15:47:31 2009	(r197362)
 +++ head/usr.bin/find/find.1	Sun Sep 20 16:47:56 2009	(r197363)
 @@ -312,6 +312,7 @@ character in its pathname relative to
  .Dq Pa \&.
  for security reasons.
  Depth-first traversal processing is implied by this option.
 +Following symlinks is incompatible with this option.
  .It Ic -depth
  Always true;
  same as the
 @@ -920,7 +921,7 @@ recent than the current time minus one m
  Use the
  .Xr echo 1
  command to print out a list of all the files.
 -.It Li "find -L /usr/ports/packages -type l -delete"
 +.It Li "find -L /usr/ports/packages -type l -exec rm -- {} +"
  Delete all broken symbolic links in
  .Pa /usr/ports/packages .
  .It Li "find /usr/src -name CVS -prune -o -depth +6 -print"
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/90687: commit references a PR
Date: Sun,  4 Oct 2009 17:23:04 +0000 (UTC)

 Author: jilles
 Date: Sun Oct  4 17:22:51 2009
 New Revision: 197749
 URL: http://svn.freebsd.org/changeset/base/197749
 
 Log:
   MFC r197363: Update find(1) man page for -L/-delete interaction.
   
   It is a bit unfortunate that the example to delete broken symlinks now uses
   rm(1), but allowing this with -delete would require fixing fts(3) to not
   imply FTS_NOCHDIR if FTS_LOGICAL is given (or hacks in the -delete option).
   
   PR:		bin/90687
 
 Modified:
   stable/7/usr.bin/find/   (props changed)
   stable/7/usr.bin/find/find.1
 
 Modified: stable/7/usr.bin/find/find.1
 ==============================================================================
 --- stable/7/usr.bin/find/find.1	Sun Oct  4 17:16:11 2009	(r197748)
 +++ stable/7/usr.bin/find/find.1	Sun Oct  4 17:22:51 2009	(r197749)
 @@ -306,6 +306,7 @@ character in its pathname relative to
  .Dq Pa \&.
  for security reasons.
  Depth-first traversal processing is implied by this option.
 +Following symlinks is incompatible with this option.
  .It Ic -depth
  Always true;
  same as the
 @@ -843,7 +844,7 @@ recent than the current time minus one m
  Use the
  .Xr echo 1
  command to print out a list of all the files.
 -.It Li "find -L /usr/ports/packages -type l -delete"
 +.It Li "find -L /usr/ports/packages -type l -exec rm -- {} +"
  Delete all broken symbolic links in
  .Pa /usr/ports/packages .
  .It Li "find /usr/src -name CVS -prune -o -depth +6 -print"
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/90687: commit references a PR
Date: Thu, 29 Oct 2009 21:25:27 +0000 (UTC)

 Author: jilles
 Date: Thu Oct 29 21:25:16 2009
 New Revision: 198628
 URL: http://svn.freebsd.org/changeset/base/198628
 
 Log:
   MFC r197363: Update find(1) man page for -L/-delete interaction.
   
   It is a bit unfortunate that the example to delete broken symlinks now uses
   rm(1), but allowing this with -delete would require fixing fts(3) to not
   imply FTS_NOCHDIR if FTS_LOGICAL is given (or hacks in the -delete option).
   
   PR:		bin/90687
 
 Modified:
   stable/8/usr.bin/find/   (props changed)
   stable/8/usr.bin/find/find.1
 
 Modified: stable/8/usr.bin/find/find.1
 ==============================================================================
 --- stable/8/usr.bin/find/find.1	Thu Oct 29 21:23:44 2009	(r198627)
 +++ stable/8/usr.bin/find/find.1	Thu Oct 29 21:25:16 2009	(r198628)
 @@ -312,6 +312,7 @@ character in its pathname relative to
  .Dq Pa \&.
  for security reasons.
  Depth-first traversal processing is implied by this option.
 +Following symlinks is incompatible with this option.
  .It Ic -depth
  Always true;
  same as the
 @@ -920,7 +921,7 @@ recent than the current time minus one m
  Use the
  .Xr echo 1
  command to print out a list of all the files.
 -.It Li "find -L /usr/ports/packages -type l -delete"
 +.It Li "find -L /usr/ports/packages -type l -exec rm -- {} +"
  Delete all broken symbolic links in
  .Pa /usr/ports/packages .
  .It Li "find /usr/src -name CVS -prune -o -depth +6 -print"
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->closed 
State-Changed-By: avg 
State-Changed-When: Mon Jan 18 15:32:14 UTC 2010 
State-Changed-Why:  
I think that the PR is resolved within the scope of 
the original report/request. 
If any further enhancements to find(1) in this area are 
wanted or proposed, then they should be filed under a new PR. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=90687 
>Unformatted:
