Skip to content

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

Closed

Description

@oojacoboo

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?

Activity

  1. tianon commented on Sep 22, 2017

    @tianon
    Member

    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.)

  2. oojacoboo commented on Sep 22, 2017

    @oojacoboo
    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.

  3. tianon commented on Oct 12, 2017

    @tianon
    Member

    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!

  4. oojacoboo commented on Oct 12, 2017

    @oojacoboo
    Author

    @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.

  5. TrurlMcByte commented on Oct 12, 2017

    @TrurlMcByte

    @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
    
  6. TrurlMcByte commented on Oct 12, 2017

    @TrurlMcByte

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

  7. TrurlMcByte commented on Oct 12, 2017

    @TrurlMcByte

    --cap-add SYS_PTRACE is enough

  8. tianon commented on Oct 12, 2017

    @tianon
    Member

    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).

  9. reopened this on Oct 12, 2017
  10. oojacoboo commented on Oct 12, 2017

    @oojacoboo
    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.

  11. tianon commented on Oct 12, 2017

    @tianon
    Member
  12. oojacoboo commented on Oct 13, 2017

    @oojacoboo
    Author

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

  13. TrurlMcByte commented on Oct 13, 2017

    @TrurlMcByte

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

  14. tianon commented on Oct 13, 2017

    @tianon
    Member

    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.)

  15. TrurlMcByte commented on Oct 14, 2017

    @TrurlMcByte

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

  16. tianon commented on Dec 23, 2017

    @tianon
    Member

    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.

  17. tianon commented on Dec 23, 2017

    @tianon
    Member

    (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.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions