Date: Sat, 25 May 2013 16:46:47 +0300 From: Johan Myreen <jem@iki.fi> To: freebsd-cvsweb@FreeBSD.org Subject: Bug related to ACLs in cvsweb Message-ID: <51A0C0C7.4080104@iki.fi>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. --------------000904040501080507090103 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Hi. Due to a Perl misfeature, cvsweb.cgi does not work correctly if Access Control Lists (ACLs) are in use. The script includes the pragma use filetest qw(access); This pragma changes how Perl does permission checks on files and directories; instead of using stat(), permissions are checked using access(). The problem is that the script uses the cached value of a stat() call to check permissions, using the special filehandle _. When the filetest 'access' pragma is in use, the -r $file, -w $file and -x $file tests do not set the cache (because no call to stat() is made). What's worse, when the stat cache is set, e.g. as a result of -d $file, it contains the wrong value for a -r _ test. The stat cache contains the traditional rwx mode bits, and does not reflect any additional permissions granted by the ACL. See: http://perldoc.perl.org/filetest.html ACLs are very useful when used with cvsweb. You can grant the 'www-data' user read permission to the repository files without opening them up to all users on the server (with chmod o+r). Of course, you could add user 'www-data' to the 'cvs' group, but that would mean 'www-data' would have write permission to the repository. Patch attached. Keywords: cvsweb acl bug filetest access Johan Myréen jem@iki.fi --------------000904040501080507090103 Content-Type: text/x-patch; name="cvsweb.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="cvsweb.diff" diff -u cvsweb-3.0.6-orig/cvsweb.cgi cvsweb-3.0.6/cvsweb.cgi --- cvsweb-3.0.6-orig/cvsweb.cgi 2005-09-25 23:28:51.000000000 +0300 +++ cvsweb-3.0.6/cvsweb.cgi 2013-05-25 15:01:58.000000000 +0300 @@ -990,10 +990,11 @@ next if ($input{hidecvsroot} && $where eq '/' && $file eq 'CVSROOT'); # Is it a directory? - my $isdir = -d catdir($fullname, $file); + my $subdir = catdir($fullname, $file); + my $isdir = -d $subdir; # Ignore non-readable files and directories? - next if ($input{hidenonreadable} && (! -r _ || ($isdir && ! -x _))); + next if ($input{hidenonreadable} && (! -r $subdir || ($isdir && ! -x $subdir))); my $attic = ''; if ($file =~ s|^Attic/||) { @@ -1459,8 +1460,8 @@ ($filename) = (catfile($dirname, $filename) =~ VALID_PATH) or next; # untaint my ($file) = catfile($fullname, $filename); - next if ($filename !~ /,v$/o || !-f $file || !-r _); - my $modtime = -M _; + next if ($filename !~ /,v$/o || !-f $file || !-r $file); + my $modtime = -M $file; if (!defined($lastmod) || $modtime < $lastmodtime) { ($lastmod = $filename) =~ s/,v$//; $lastmodtime = $modtime; @@ -1718,7 +1719,7 @@ my ($command) = @_; for my $d (@command_path) { my $cmd = catfile($d, $command); - return $cmd if (-x $cmd && !-d _); + return $cmd if (-x $cmd && !-d $cmd); } return ''; } @@ -1753,7 +1754,7 @@ my $mimetype = $MTYPES{$suffix}; $mimetype ||= $MimeTypes->mimeTypeOf($fullname) if defined($MimeTypes); - if (!$mimetype && $suffix ne '*' && -f $mime_types && -r _) { + if (!$mimetype && $suffix ne '*' && -f $mime_types && -r $mime_types) { my $fh = do { local (*FH); }; if (open($fh, $mime_types)) { my $re = sprintf('^\s*(\S+\/\S+)\s.+\b%s\b', quotemeta($suffix)); @@ -2454,7 +2455,7 @@ # Note: last modified files from subdirs returned by # findLastModifiedSubdirs() come without the ,v suffix so they're not # found here, but have already been checked for readability. *cough* - if (-r $files[$i] || !-e _) { + if (-r $files[$i] || !-e $files[$i]) { $i++; } else { push(@unreadable, splice(@files, $i, 1)); --------------000904040501080507090103--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?51A0C0C7.4080104>