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.
The way I see it, there are only two options:
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.)
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
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:
pgrep apache2 -o
/proc/PID/mountinfo
file, which contains the mount info as seen by this processgrep
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With