X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_13,SARE_MSGID_LONG40,SPF_PASS X-Spam-Check-By: sourceware.org MIME-Version: 1.0 In-Reply-To: <20090811070045.GZ3204@calimero.vinschen.de> References: <20090810132515 DOT GP3204 AT calimero DOT vinschen DOT de> <20090810164057 DOT GV3204 AT calimero DOT vinschen DOT de> <6910a60908101701m77bcb1b3x55e48d028bf35ef0 AT mail DOT gmail DOT com> <6910a60908101949k5f2ce354p1ccda7f2acd9927f AT mail DOT gmail DOT com> <20090811070045 DOT GZ3204 AT calimero DOT vinschen DOT de> Date: Tue, 11 Aug 2009 12:44:36 +0200 Message-ID: <6910a60908110344n56b7a7f9j9ead9ceeae6a1608@mail.gmail.com> Subject: Re: Perl bug (was Re: [1.7] cygwin allows writing to readonly files) From: Reini Urban To: cygwin AT cygwin DOT com Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com 2009/8/11 Corinna Vinschen: > On Aug 11 04:49, Reini Urban wrote: >> 2009/8/11 Reini Urban: >> > 2009/8/10 Corinna Vinschen: >> >> On Aug 10 20:11, Alexey Borzenkov wrote: >> >>> Anyway, it means there is a bug in perl, because on Linux: >> >>> >> >>> root AT kitsu:~# touch test.txt >> >>> root AT kitsu:~# chmod 0444 test.txt >> >>> root AT kitsu:~# perl -e 'print "writable\n" if -w "test.txt"' >> >>> writable >> >>> >> >>> On Cygwin 1.7 perl thinks that the file is not writable. >> >> >> >> Indeed. =A0Checking with strace I found that the test is the same on = Linux >> >> and Cygwin. =A0In both cases perl uses stat(), and the returned permi= ssions >> >> are the same (0444). =A0Further experimenting shows that perl has a >> >> hardcoded uid =3D=3D 0 test which must obviously fail on Cygwin. =A0I= f I change >> >> the user's uid to 0, the string "writable" is printed by the above co= mmand. >> >> >> >> That's a bug in perl. =A0There are other OSes out there which have >> >> root-like permissions for non-0 uids. =A0Perl should use the access() >> >> function to check for read/write/execute permissions, which always >> >> returns the correct result independent of the uid of the current user. >> > >> > Thanks. >> > I'll carry it along to p5p, but it will definitely not appear in >> > upstream 5.10.1 >> > because this gate is already closed. >> > Even a horrible performance problem with >> > File::Spec::Cygwin::case_tolerant was not fixed. >> > >> > But I work on a fix to be included in blead and in my cygwin package. >> >> Bug confirmed too early. It's actually defined and described this way. >> access() is not used for performance reasons. See perldoc perlfunc -X >> >> If you are using ACLs, there is a pragma called C that may >> produce more accurate results than the bare stat() mode bits. >> When under the C the above-mentioned filetests >> will test whether the permission can (not) be granted using the >> access() family of system calls. =A0Also note that the C<-x> and C<-X> m= ay >> under this pragma return true even if there are no execute permission >> bits set (nor any extra execute permission ACLs). =A0This strangeness is >> due to the underlying system calls' definitions. Note also that, due to >> the implementation of C, the C<_> special >> filehandle won't cache the results of the file tests when this pragma is >> in effect. =A0Read the documentation for the C pragma for more >> information. > > As far as I'm concerned this is still a bug. =A0It will result in > different behaviour of the same script on different platforms for no > apparent reason. > >> $ ./perl -e 'print "writable\n" if -w "test.txt"' >> >> $ ./perl -e 'use filetest "access"; print "writable\n" if -w "test.txt"' >> writable >> >> I can turn on access checks easily for CYGWIN but cygwin perl is already >> slow enough, so I will not do that. >> >> Changing the uid=3D=3D0 check to check the Administrators gid is more pr= omising. >> i.e. >> --- doio.c.orig 2009-04-18 19:17:04.000000000 +0200 >> +++ doio.c =A0 =A0 =A02009-08-11 04:46:09.343750000 +0200 >> @@ -1918,7 +1918,11 @@ >> =A0 =A0 =A0 return (mode & statbufp->st_mode) ? TRUE : FALSE; >> >> =A0#else /* ! DOSISH */ >> +# ifndef __CYGWIN__ >> =A0 =A0 =A0if ((effective ? PL_euid : PL_uid) =3D=3D 0) { /* root is spe= cial */ >> +# else >> + =A0 =A0if ((effective ? PL_egid : PL_gid) =3D=3D 544) { /* member of >> Administrators? */ >> +# endif >> =A0 =A0 =A0 =A0 if (mode =3D=3D S_IXUSR) { >> =A0 =A0 =A0 =A0 =A0 =A0 if (statbufp->st_mode & 0111 || S_ISDIR(statbufp= ->st_mode)) >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 return TRUE; >> >> but this didn't help me, because Administrators is not my first group. >> So I call this a known limitation for all ACL aware filesystems. > > That might be a good workaround nevertheless. =A0You should just test the > list of supplementary groups as well, along these lines: We already have an ingroup() check in this Perl_cando() function, so there is no need to write it again. But it is disabled in perl core for this code path. See http://perl5.git.perl.org/perl.git/blob/HEAD:/doio.c#l1929 It would be: if (ingroup(544,effective)) return TRUE; /* Administrators read and write anything */ but this is simply not true, as under unix. Windows Administrators fall under the same ACL restrictions as normal users. So only using access() is reliable. I rather suggest to add the filetest access hint to the failing ExtUtils::MakeMaker module, and Module::Install and Module::Build also. --=20 Reini Urban http://phpwiki.org/ http://murbreak.at/ -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple