Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP: way to get the true /tmp path?

I'm moving my web app from CentOS 5 to CentOS 7, and new security features regarding the /tmp directory are breaking my code. I'm wondering how best to handle it.

I have PHP code that creates a LaTeX file, then executes commands to turn that into a PDF, and then serves that to the user with appropriate headers. Here are some of the relevant lines of code as it stands now:

$fileroot = "/tmp/addr".getmypid();
ob_start();
/* echo all the LaTeX stuff */
file_put_contents($fileroot.".tex",ob_get_contents());
ob_end_clean();
exec("cd /tmp;uplatex -interaction=batchmode --output-directory=/tmp $fileroot", $output, $return);

The settings in /usr/lib/systemd/system/php-fpm.service include PrivateTmp=true, which causes /tmp within PHP function calls to really be /tmp/systemd-private-6898f2d665d64b998981bc479ddc2306-php-fpm.service-KU8XML/tmp. Yikes! That's fine for security, but exec() uses the /tmp path literally, so it can't find the file that file_put_contents() just created. The PHP function sys_get_temp_dir() just returns /tmp, and I can't find any environment variables with that path in them. Is there a way to get that path programmatically? Or do I need to turn off PrivateTmp? Or is there a better way to do what I need to do? Yes, I could create my own special spot with wide-open permissions, but it seems like it should be cleaner to just use the normal temporary directory.

like image 295
OsakaWebbie Avatar asked Mar 10 '23 02:03

OsakaWebbie


2 Answers

The way I see it, there are only two options:

  1. Do not use /tmp but a different directory instead, which you predefine in your application's config file. I have done something similar recently, where I used /var/run/myapplication directory instead of /tmp. (I had to add a cron job to clean it up as well.)

  2. Disable PrivateTmp in the php-frm service. Here's one way of doing this:

    # mkdir  /usr/lib/systemd/system/php-fpm.service.d
    # echo -e "[Service]\nPrivateTmp=no" > /etc/systemd/system/php-fpm.service.d/privatetmp.conf
    # systemctl daemon-reload
    # systemctl restart php-fpm
    
    # systemctl show php-fpm | grep PrivateTmp
    PrivateTmp=no
    
like image 183
Aleks G Avatar answered Mar 20 '23 00:03

Aleks G


I just had a similar issue. This is a way to find out the "real" temp path of a systemd service with PrivateTmp (in this case apache2):

 grep -oP ' /tmp/systemd-private-[^/]+-apache2[^/]+/tmp(?= /tmp)' /proc/`pgrep apache2 -o`/mountinfo

What it does:

  • search for the process id of the oldest apache2 process: pgrep apache2 -o
  • read the /proc/PID/mountinfo file, which contains the mount info as seen by this process
  • extract the private tmp folder with a regular expression using grep

It may be that with future systemd versions or different settings, the regex needs to be adjusted, if the naming is different. You may also just use ' /tmp[^ ]+(?= /tmp)' as the regex.

Note that it may not help you much to know the path. Private temp folders have strict permissions that only allow root access.

like image 30
Christopher K. Avatar answered Mar 20 '23 01:03

Christopher K.