Skip to content

php-fpm permission denied on /proc/$id/mem #498

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
oojacoboo opened this issue Sep 21, 2017 · 16 comments
Closed

php-fpm permission denied on /proc/$id/mem #498

oojacoboo opened this issue Sep 21, 2017 · 16 comments

Comments

@oojacoboo
Copy link

oojacoboo commented Sep 21, 2017

I get the following output to stderr from the php container.

api-php  | [21-Sep-2017 21:49:18] WARNING: [pool www] child 13, script '/srv/www/public/index.php' (request: "GET /something") executing too slow (25.593270 sec), logging
api-php  | [21-Sep-2017 21:49:18] NOTICE: child 13 stopped for tracing
api-php  | [21-Sep-2017 21:49:18] NOTICE: about to trace 13
api-php  | [21-Sep-2017 21:49:18] ERROR: failed to open /proc/13/mem: Permission denied (13)
api-php  | [21-Sep-2017 21:49:18] NOTICE: finished trace of 13
root@f161350c4858:/srv/www# id
uid=0(root) gid=0(root) groups=0(root)

root@f161350c4858:/srv/www# id www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
root@f161350c4858:/srv/www# ls -lash /proc/13/mem
0 -rw------- 1 www-data www-data 0 Sep 21 21:49 /proc/13/mem
root@f161350c4858:/srv/www# cat /proc/13/mem
cat: /proc/13/mem: Permission denied

Now, the slowlog would be a PHP-FPM running as root. However, it's my understanding that /proc is a special kernel access dir and does not conform to standard permissions, instead obeying the UID/GID values to determine process authorization for accessing memory space. This is obviously for security purposes.

I'm not really sure what the solution here is. Maybe this is even a PHP-FPM design flaw?

@tianon
Copy link
Member

tianon commented Sep 22, 2017

It looks like it's reading /proc/$$/mem in https://github.com/php/php-src/blob/6053987bc27e8dede37f437193a5cad448f99bce/sapi/fpm/fpm/fpm_trace_pread.c#L40, but I'm not 100% sure why -- it's talking about "tracing", which Docker's definitely blocking (likely in the default seccomp profile and possibly via capabilities), but I'm not familiar enough with this part of PHP-FPM to say much more than that. 😞

(It's definitely by design that PHP-FPM is doing this, and also definitely by design that Docker is blocking it by default.)

@oojacoboo
Copy link
Author

@tianon good find. The reason, as I understand it that php-fpm is reading this is because it needs to get the trace details for the slow_log. PHP-FPM wouldn't really have access to this any other way, unless PHP somehow passed it all back to FPM, but that wouldn't work without an explicit call to PHP since PHP isn't going to know how long the call is taking. This is a PHP-FPM concern.

I'm wondering if this is working on a bare metal install of Debian.

@tianon
Copy link
Member

tianon commented Oct 12, 2017

I imagine that this works fine on a bare metal install of Debian because it won't be applying the same security constraints by default that Docker is, and PHP-FPM will likely be able to read it's own memory file just fine.

Regardless, this is really working-as-designed, so further comments/questions should likely be posted to the Docker Community Forums, the Docker Community Slack, or Stack Overflow. Thanks!

@tianon tianon closed this as completed Oct 12, 2017
@oojacoboo
Copy link
Author

oojacoboo commented Oct 12, 2017

@tianon I respect that this issue may not be rooted in this docker container implementation. However, respectfully, I disagree with closing this issue until there is a resolution since it flat out does not work.

@TrurlMcByte
Copy link

@oojacoboo I've trying with owner permission (under CoreOS), but get another error

/var/www/html $ id
uid=82(www-data) gid=82(www-data) groups=82(www-data)
/var/www/html $ ps
PID   USER     TIME   COMMAND
    1 root       0:00 php-fpm: master process (/usr/local/etc/php-fpm.conf)
   48 www-data   0:16 php-fpm: pool www
   53 www-data   0:00 sh
   62 www-data   0:01 php-fpm: pool www
   63 www-data   0:00 php-fpm: pool www
   65 www-data   0:00 ps
/var/www/html $ cat /proc/48/mem
cat: read error: I/O error

@TrurlMcByte
Copy link

--cap-add all solve this problem, will check more

@TrurlMcByte
Copy link

--cap-add SYS_PTRACE is enough

@tianon
Copy link
Member

tianon commented Oct 12, 2017

I'm still unable to reproduce an issue here -- are the systems you're testing on using AppArmor or SELinux? (I guess CoreOS is likely using SELinux, but odd that --cap-add SYS_PTRACE works when I don't have an issue running the PHP-FPM container as-is and I don't have AppArmor or SELinux, but obviously do have the same set of default capabilities.)

$ docker pull php:7-fpm
7-fpm: Pulling from library/php
Digest: sha256:d8ebbb9f1146af10ec9b05943f82197d99b92d6e25516d82291f6d50419f4f4b
Status: Image is up to date for php:7-fpm

$ docker run -it --rm php:7-fpm
[12-Oct-2017 21:51:56] NOTICE: fpm is running, pid 1
[12-Oct-2017 21:51:56] NOTICE: ready to handle connections

See also https://travis-ci.org/docker-library/php/jobs/286978534#L2972, where Travis runs our php-fpm-hello-web test successfully (https://github.com/docker-library/official-images/blob/5b0acc55af0bdfc198407153d4e55b0248cb3843/test/tests/php-fpm-hello-web/run.sh), which also does not do anything special beyond simply docker run (and runs successfully on systems which have AppArmor enabled, but hasn't been tested on SELinux).

@tianon tianon reopened this Oct 12, 2017
@oojacoboo
Copy link
Author

@tianon PHP-FPM runs fine for most operations. As you can see in my case, it's when trying to write to the slow_log that's the issue.

I'm not using AppArmor or SELinux. I'm using the pretty default php:7.1-fpm container.

@tianon
Copy link
Member

tianon commented Oct 12, 2017 via email

@oojacoboo
Copy link
Author

Right, it only fails to write the slow_log. This is a PHP-FPM error, everything else works perfectly fine.

@TrurlMcByte
Copy link

@oojacoboo Just run container with --cap-add SYS_PTRACE option, it's solve issue with tracing

@tianon
Copy link
Member

tianon commented Oct 13, 2017

So, it looks like the only thing that's actionable here is to add a brief note to the documentation that if request_slowlog_timeout is enabled, one should include --cap-add SYS_PTRACE in order for PHP-FPM to read the PHP backtrace, right?

(Probably with a link to https://secure.php.net/manual/en/install.fpm.configuration.php#request-slowlog-timeout for context.)

@TrurlMcByte
Copy link

@tianon Right. But not sure if it's only one tracing call.

@tianon
Copy link
Member

tianon commented Dec 23, 2017

I guess my advice from #241 (comment) applies here too (and it'd probably make sense to combine the two into a single PR on the docs), namely that we need a variant-fpm.md file for the php image over in the docs which describes configuration and notes that --cap-add SYS_PTRACE is necessary if request_slowlog_timeout is enabled.

@tianon
Copy link
Member

tianon commented Dec 23, 2017

(Noted that over on #241 now -- closing this in favor of that one since we need general documentation about configuring FPM anyhow, which is what that issue covers.)

@tianon tianon closed this as completed Dec 23, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants