I'm trying to write to a file in /tmp
directory which has permissions: drwxrwxrwt
. When I execute file_put_contents
from php -a
interactive shell, it works alright and creates a file with the provided content. When I call this function in the code, it returns the number of bytes written to the file but no file is created at the target directory. No error is thrown anywhere in php and/or apache2 logs.
Following call is being made in the code.
// both $k and $version are defined and have values
file_put_contents('/tmp/' . $k . '-version.php', '<?php $version = "' . $version . '";');
I'm out of debugging options here. What can be the cause of this?
I'm calling the function via curl through command line.
Debugging
Debugging steps as mentioned by @progman in the comments:
Variable dump
Code:
$path = '/tmp/' . $k . '-version.php';
file_put_contents($path, '<?php $version = "' . $version . '";');
var_dump($path, file_exists($path), is_file($path), is_writable($path));
Output:
string(34) "/tmp/fullpagewidgetnew-version.php"
bool(true)
bool(true)
bool(true)
Shell Command Executions
Added the shell command in code to see the output:
Code: echo shell_exec('ls /tmp');
Output
fullpagewidgetnew-version.php
While doing ls /tmp
right after the call, I get a couple of other files created by other processes, but it doesn't have the file I created through code.
mongodb-27017.sock symlink-dummy systemd-private-64efbd330d8d4df09fc1634371bee3d5-nagios-nrpe-server.service-ZRy81Y tmp.XwUT7dI5RP
sigdump-1018.log systemd-private-64efbd330d8d4df09fc1634371bee3d5-apache2.service-aWwjlA systemd-private-64efbd330d8d4df09fc1634371bee3d5-systemd-resolved.service-wDp3ys
sigdump-1023.log systemd-private-64efbd330d8d4df09fc1634371bee3d5-do-agent.service-u4rdtA systemd-private-64efbd330d8d4df09fc1634371bee3d5-systemd-timesyncd.service-IRGXmZ
stat
command execution
Code: echo shell_exec('ls /tmp');
Output:
File: /tmp
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fc01h/64513d Inode: 1508 Links: 2
Access: (1777/drwxrwxrwt) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-11-01 13:26:33.766987581 +0000
Modify: 2020-11-01 07:00:03.958583691 +0000
Change: 2020-11-01 07:00:03.958583691 +0000
Birth: -
Direct shell execution stat /tmp
:
File: /tmp
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fc01h/64513d Inode: 4037 Links: 14
Access: (1777/drwxrwxrwt) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-11-01 18:04:39.853667091 +0000
Modify: 2020-11-01 18:01:39.463721617 +0000
Change: 2020-11-01 18:01:39.463721617 +0000
Birth: -
Code: echo shell_exec('ls /');
Output:
File: /
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fc01h/64513d Inode: 2 Links: 23
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-10-31 18:09:33.585968968 +0000
Modify: 2020-10-21 15:39:29.371174584 +0000
Change: 2020-10-21 15:39:29.371174584 +0000
Birth: -
Direct shell execution stat /
:
File: /
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fc01h/64513d Inode: 2 Links: 23
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2020-10-31 18:09:33.585968968 +0000
Modify: 2020-10-21 15:39:29.371174584 +0000
Change: 2020-10-21 15:39:29.371174584 +0000
Birth: -
Solution
Turned out that PrivateTmp=true
in apache's systemd script. That was creating a separate tmp directory inside the tmp directory. Can't write to /tmp with php, despite 777 permissions and no open_basedir value
I couldn't answer the question because it was locked, that's why posting the solution here in the question.