Req #69090 [Opn->Ana]: add prefix/xor to cache keys/check permissions or separate caches

From: Date: Sat, 21 Feb 2015 02:00:41 +0000
Subject: Req #69090 [Opn->Ana]: add prefix/xor to cache keys/check permissions or separate caches
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-190861@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=69090&edit=1

 ID:                 69090
 Updated by:         rasmus@php.net
 Reported by:        simon at ikanobori dot jp
 Summary:            add prefix/xor to cache keys/check permissions or
                     separate caches
-Status:             Open
+Status:             Analyzed
 Type:               Feature/Change Request
 Package:            opcache
 Operating System:   linux/debian
 PHP Version:        5.6.5
 Block user comment: N
 Private report:     N

 New Comment:

I think the easiest would be to simply add an option to use a file's device+inode in addition
to, or instead of, the full path. We have discussed this a few times, but nobody has gotten around
to an implementation yet.


Previous Comments:
------------------------------------------------------------------------
[2015-02-20 14:38:50] simon at ikanobori dot jp

Correct PHP version.

------------------------------------------------------------------------
[2015-02-20 14:37:23] simon at ikanobori dot jp

Description:
------------
PHP's opcache seems to create keys for files it caches based on their filepath (including the
cwd when the option opcache.use_cwd is set).

When turning on opcache in commonly used hosting environments where users are chrooted it is very
easy to get key collissions as the full path of a file in a chroot can commonly be /wp-config.php.
The file that was accessed on this path first will be stored by opcache and be used by any
interpreters executing the same file later on.

Even without a chroot it is often easy to predict where files of another user on the same server
will be located and they can still be included circumventing any file permissions set on these files
even if PHP executes as the correct user (made even more trivial to figure out interesting files if
access to the opcache_get_status() function is not restricted by the host).

Example is in the "test script" below which shortly shows my relevant config lines.

It'd be neat if opcache could implement a runtime config variable to give to an interpreter
with a value that mashes up the key by prefixing or xor'ing it without the possibility of being
overwritten from within the script.

Alternatively it might be possible to use different parts of shm based on a configuration option so
the cache is per-user.

Test script:
---------------
# Permissions on both directories and files are set to rwx for user only
root@debian:/home# ls -l .
total 12
drwx------ 2 one       one       4096 Feb 20 12:45 one
drwx------ 2 two       two       4096 Feb 20 12:45 two

root@debian:/home# ls -l one/
total 4
-rw------- 1 one one 25 Feb 20 12:42 one.php

root@debian:/home# ls -l two/
total 4
-rw------- 1 two two 46 Feb 20 12:44 two.php

# one.php just sets a single variable
root@debian:/home# cat one/one.php 
<?php

$one = "one";

?>

# This file tries to include the non-existent "/one.php" in its chroot
root@debian:/home# cat two/two.php 
<?php

	include "/one.php";

	print $one;

?>

# FPM processes are configured to run as the user           
root@debian:/home# grep -r "user =" /etc/php5/fpm/pool.d/
/etc/php5/fpm/pool.d/1.conf:user = one
/etc/php5/fpm/pool.d/2.conf:user = two

# FPM processes also run chrooted into the homedirs
root@debian:/home# grep -r "chroot " /etc/php5/fpm/pool.d/
/etc/php5/fpm/pool.d/1.conf:chroot = /home/one
/etc/php5/fpm/pool.d/2.conf:chroot = /home/two

# Request one.php on pool one
root@debian:/home# curl http://1.localhost/one.php

# Request two.php on pool two
root@debian:/home# curl http://2.localhost/two.php
one

# That's the content of /one.php which is owned by user one, in its own chroot
# being served by user two from a different chroot while user two doesnt even
# have read permissions on the file.

Expected result:
----------------
Users can only access their own files (when configured correctly).

Actual result:
--------------
Users can access other users' files when previously accessed by opcache cross chroots and
ignoring filesystem permissions.


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=69090&edit=1


Thread (38 messages)

« previous php.bugs (#190861) next »