Discussion:
[perl #125788] Perl second-guesses Cygwin for permission override, sometimes incorrectly
via RT
2015-08-11 15:31:31 UTC
Permalink
# New Ticket Created by
# Please include the string: [perl #125788]
# in the subject line of all future correspondence about this issue.
# <URL: https://rt.perl.org/Ticket/Display.html?id=125788 >



This is a bug report for perl from ***@mail.mipt.ru,
generated with the help of perlbug 1.40 running under perl 5.23.2.


-----------------------------------------------------------------
[Please describe your issue here]

Follow-up of #125740.

When checking `-r/-w file', pp_ftrread (pp_sys.c:3071)
does a `stat', then, in `Perl_cando' (doio.c:2065)
guesses whether to override its results.

Sometimes, it guesses incorrectly:
1) In some cases where Cygwin uses an old ID mapping (https://rt.perl.org/Public/Bug/Display.html?id=125740#txn-1360344)
2) When a user is not a member of Administrators but holds SeBackupPrivilege/SeRestorePrivilege (https://rt.perl.org/Public/Bug/Display.html?id=125740#txn-1359529). Moreover, Cygwin correctly makes SeBackupPrivilege override only read and SeRestorePrivilege - only write.

Since commit https://cygwin.com/git/gitweb.cgi?p=newlib-cygwin.git;a=commit;h=2c1ffdbf5e6f2767ab63e67834530539d36c6c0b,
Cygwin supports the overriding itself in its faccessat/eaccess/access.
So it's better not to second-guess it.


[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
category=core
severity=low
---
Site configuration information for perl 5.23.2:

Configured by User at Fri Aug 7 11:37:29 AST 2015.

Summary of my perl5 (revision 5 version 23 subversion 2) configuration:
Derived from: 2245a2697d9662043aa9aa1fdfc9002e9438a089
Ancestor: 85d323d4d59cc15f5c76bca4c1df90317f88d0e8
Platform:
osname=cygwin, osvers=2.2.0(0.28953), archname=cygwin-thread-multi-64int
uname='cygwin_nt-5.1 iru-notebook 2.2.0(0.28953) 2015-08-03 12:49 i686 cygwin '
config_args='-Dprefix=/opt/perl5 -Dusedevel -Doptimize=-O0 -ggdb3 -Dldflags=-ggdb3 -DDEBUGGING -de'
hint=recommended, useposix=true, d_sigaction=define
useithreads=define, usemultiplicity=define
use64bitint=define, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='gcc', ccflags ='-DPERL_USE_SAFE_PUTENV -U__STRICT_ANSI__ -fwrapv -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector-strong -D_FORTIFY_SOURCE=2',
optimize='-O0 -ggdb3',
cppflags='-DPERL_USE_SAFE_PUTENV -U__STRICT_ANSI__ -fwrapv -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector-strong'
ccversion='', gccversion='4.9.3', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678, doublekind=3
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12, longdblkind=3
ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries:
ld='g++', ldflags ='-ggdb3 -Wl,--enable-auto-import -Wl,--export-all-symbols -Wl,--enable-auto-image-base -fstack-protector-strong -L/usr/local/lib'
libpth=/usr/local/lib /usr/lib /lib
libs=-lpthread -ldl -lcrypt
perllibs=-lpthread -ldl -lcrypt
libc=/usr/lib/libc.a, so=dll, useshrplib=true, libperl=cygperl5_23_2.dll
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags=' --shared -ggdb3 -Wl,--enable-auto-import -Wl,--export-all-symbols -Wl,--enable-auto-image-base -L/usr/local/lib -fstack-protector-strong'

Locally applied patches:
uncommitted-changes
a90ad6d3cfecd7f26e2a8932159963ea31307bca
77890ada5ef197f9be3406cfe66be13e91f48b84
2245a2697d9662043aa9aa1fdfc9002e9438a089

---
@INC for perl 5.23.2:
lib
/opt/perl5/lib/site_perl/5.23.2/cygwin-thread-multi-64int
/opt/perl5/lib/site_perl/5.23.2
/opt/perl5/lib/5.23.2/cygwin-thread-multi-64int
/opt/perl5/lib/5.23.2
.

---
Environment for perl 5.23.2:
CYGWIN=nodosfilewarning
HOME=/home/User
LANG=RU
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/usr/local/bin:/usr/bin:/c/bin/rk:/c/WINDOWS/system32:/c/WINDOWS:/c/WINDOWS/system32/WBEM:/c/Py/Scripts:/c/Py:/usr/local/bin:/usr/bin:/:/c/bin:%JAVA_HOME%/bin:/c/Program Files/QT Lite/QTSystem:/c/Program Files/TortoiseSVN/bin:/c/Program Files/TortoiseGit/bin:/c/Program Files/Git/cmd:/c/Program Files/TortoiseHg:/c/program files/vim/vim71:/c/Program Files/PuTTY:/c/Program Files/Nmap
PERL_BADLANG (unset)
SHELL=/bin/bash
Tony Cook via RT
2015-08-13 05:16:21 UTC
Permalink
Post by via RT
Follow-up of #125740.
When checking `-r/-w file', pp_ftrread (pp_sys.c:3071)
does a `stat', then, in `Perl_cando' (doio.c:2065)
guesses whether to override its results.
1) In some cases where Cygwin uses an old ID mapping
(https://rt.perl.org/Public/Bug/Display.html?id=125740#txn-1360344)
2) When a user is not a member of Administrators but holds
SeBackupPrivilege/SeRestorePrivilege
(https://rt.perl.org/Public/Bug/Display.html?id=125740#txn-1359529).
Moreover, Cygwin correctly makes SeBackupPrivilege override only read
and SeRestorePrivilege - only write.
Since commit https://cygwin.com/git/gitweb.cgi?p=newlib-
cygwin.git;a=commit;h=2c1ffdbf5e6f2767ab63e67834530539d36c6c0b,
Cygwin supports the overriding itself in its faccessat/eaccess/access.
So it's better not to second-guess it.
That the permission check operators work off the mode is explicitly documented (from =item -X in perlfunc.pod):

The interpretation of the file permission operators C<-r>, C<-R>,
C<-w>, C<-W>, C<-x>, and C<-X> is by default based solely on the mode
of the file and the uids and gids of the user. There may be other
reasons you can't actually read, write, or execute the file: for
example network filesystem access controls, ACLs (access control lists),
read-only filesystems, and unrecognized executable formats. Note
that the use of these six specific operators to verify if some operation
is possible is usually a mistake, because it may be open to race
conditions.

Also note that, for the superuser on the local filesystems, the C<-r>,
C<-R>, C<-w>, and C<-W> tests always return 1, and C<-x> and C<-X> return 1
if any execute bit is set in the mode. Scripts run by the superuser
may thus need to do a stat() to determine the actual mode of the file,
or temporarily set their effective uid to something else.

as is the mechanism to use access():

If you are using ACLs, there is a pragma called C<filetest> that may
produce more accurate results than the bare stat() mode bits.
When under C<use filetest 'access'> the above-mentioned filetests
test whether the permission can(not) be granted using the
access(2) family of system calls. Also note that the C<-x> and C<-X> may
under this pragma return true even if there are no execute permission
bits set (nor any extra execute permission ACLs). This strangeness is
due to the underlying system calls' definitions. Note also that, due to
the implementation of C<use filetest 'access'>, the C<_> special
filehandle won't cache the results of the file tests when this pragma is
in effect. Read the documentation for the C<filetest> pragma for more
information.

Is this documented behaviour what you were trying to report? If it was something else please provide some sample code.

Thanks,
Tony

---
via perlbug: queue: perl5 status: new
https://rt.perl.org/Ticket/Display.html?id=125788

Loading...