From owner-freebsd-bugs@FreeBSD.ORG Tue Mar 13 19:10:04 2012 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 4074C106564A for ; Tue, 13 Mar 2012 19:10:04 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 1CDAA8FC14 for ; Tue, 13 Mar 2012 19:10:04 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q2DJA3PS012830 for ; Tue, 13 Mar 2012 19:10:03 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q2DJA3LJ012829; Tue, 13 Mar 2012 19:10:03 GMT (envelope-from gnats) Resent-Date: Tue, 13 Mar 2012 19:10:03 GMT Resent-Message-Id: <201203131910.q2DJA3LJ012829@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Matthew Story Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 74C69106566B for ; Tue, 13 Mar 2012 19:08:15 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22]) by mx1.freebsd.org (Postfix) with ESMTP id 599FA8FC16 for ; Tue, 13 Mar 2012 19:08:15 +0000 (UTC) Received: from red.freebsd.org (localhost [127.0.0.1]) by red.freebsd.org (8.14.4/8.14.4) with ESMTP id q2DJ8FlH030909 for ; Tue, 13 Mar 2012 19:08:15 GMT (envelope-from nobody@red.freebsd.org) Received: (from nobody@localhost) by red.freebsd.org (8.14.4/8.14.4/Submit) id q2DJ8F9G030908; Tue, 13 Mar 2012 19:08:15 GMT (envelope-from nobody) Message-Id: <201203131908.q2DJ8F9G030908@red.freebsd.org> Date: Tue, 13 Mar 2012 19:08:15 GMT From: Matthew Story To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: bin/166056: [patch][bin] find fails with .: permission denied, even when using absolute paths X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Mar 2012 19:10:04 -0000 >Number: 166056 >Category: bin >Synopsis: [patch][bin] find fails with .: permission denied, even when using absolute paths >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Mar 13 19:10:03 UTC 2012 >Closed-Date: >Last-Modified: >Originator: Matthew Story >Release: 8.2 >Organization: >Environment: FreeBSD axe0.blackskyresearch.net 8.2-RELEASE-p2 FreeBSD 8.2-RELEASE-p2 #0: Sun Jul 3 00:57:18 EDT 2011 root@osprey.blackskyresearch.net:/usr/obj/usr/src/sys/blackskyresearch-amd64-8-2-20110702 amd64 >Description: When executing find on an absolute path (or many absolute path), find fatally errors if it cannot open ".". This is particularly problematic when running find (or programs that exec find) from cron as an underprivileged user. I can not find any reference to cwd in the POSIX 2008 specification for find, so it likely seems that this is not a violation of the specification, but it is also unnecessary. The only reason for opening "." is for the -exec primative to fork&exec in cwd of the bounding process, due to chdir calls in fts_set. If we set the FTS_NOCHDIR flag if we cannot open "." the need to chdir prior to -exec is removed. Alex Ginzburg originally discovered this behavior, so if the solution is picked up (or resolved in another way) he should be credited in the Reported By. >How-To-Repeat: >From shell $ su - # install -d -m 700 testfind # cd testfind # su notroot $ find /usr/src/usr.bin/find find: .: Permission denied Or from cron (original discovery case): * * * * * notroot find /usr/src/usr.bin/find # ... The workaround we have been using is to always cd to a safe place before running find, or a script that makes use of find ... >Fix: apply patch (patch was made against -CURRENT). patch will warn if it cannot open ".", and set the FTL_NOCHDIR flag before proceeding, below cases demonstrate functionality with&without the -exec flag $ su - # install -d -m 700 testfind # cd testfind # su notroot $ # without exec flag $ find /usr/src/usr.bin/find find: .: Permission denied /usr/src/usr.bin/find /usr/src/usr.bin/find/extern.h /usr/src/usr.bin/find/find.c /usr/src/usr.bin/find/Makefile /usr/src/usr.bin/find/function.c /usr/src/usr.bin/find/getdate.y /usr/src/usr.bin/find/find.h /usr/src/usr.bin/find/find.core /usr/src/usr.bin/find/main.c /usr/src/usr.bin/find/find.1 /usr/src/usr.bin/find/operator.c /usr/src/usr.bin/find/misc.c /usr/src/usr.bin/find/option.c /usr/src/usr.bin/find/ls.c $ with exec flag $ find /usr/src/usr.bin/find -exec pwd \; find: .: Permission denied /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind /usr/home/notroot/testfind I think the warning here is now superfluous, but I kept it as I thought some might be used to seeing this as a fatal, and it might be less arresting to lower to a warning level error as opposed to removing it as an error condition all together. Patch attached with submission follows: Index: function.c =================================================================== --- function.c (revision 232929) +++ function.c (working copy) @@ -644,7 +644,8 @@ /* NOTREACHED */ case 0: /* change dir back from where we started */ - if (!(plan->flags & F_EXECDIR) && fchdir(dotfd)) { + if (!(plan->flags & F_EXECDIR) && !(ftsoptions&FTS_NOCHDIR) + && fchdir(dotfd)) { warn("chdir"); _exit(1); } Index: find.c =================================================================== --- find.c (revision 232929) +++ find.c (working copy) @@ -179,7 +179,7 @@ tree = fts_open(paths, ftsoptions, (issort ? find_compare : NULL)); if (tree == NULL) - err(1, "ftsopen"); + err(1, "fts_open"); for (rval = 0; (entry = fts_read(tree)) != NULL;) { if (maxdepth != -1 && entry->fts_level >= maxdepth) { Index: main.c =================================================================== --- main.c (revision 232929) +++ main.c (working copy) @@ -63,7 +63,7 @@ time_t now; /* time find was run */ int dotfd; /* starting directory */ -int ftsoptions; /* options for the ftsopen(3) call */ +int ftsoptions; /* options for the fts_open(3) call */ int isdeprecated; /* using deprecated syntax */ int isdepth; /* do directories on post-order visit */ int isoutput; /* user specified output operator */ @@ -150,8 +150,10 @@ usage(); *p = NULL; - if ((dotfd = open(".", O_RDONLY, 0)) < 0) - err(1, "."); + if ((dotfd = open(".", O_RDONLY, 0)) < 0) { + warn("."); + ftsoptions |= FTS_NOCHDIR; + } exit(find_execute(find_formplan(argv), start)); } >Release-Note: >Audit-Trail: >Unformatted: