2

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.

Saqib Ahmed
  • 868
  • 15
  • 27
  • 1
    Please save the target file name in a variable, something like `$path`. Then use it in your `file_put_contents()` call and then add the function call `var_dump($path, file_exists($path), is_file($path), is_writable($path));` after the `file_put_contents()` call. Then [edit] your question to include the new source code you have and add the output you get to your question. – Progman Nov 01 '20 at 13:02
  • @Progman Updated the question – Saqib Ahmed Nov 01 '20 at 13:18
  • @SaqibAhmed So, the path exists and it is a file, it is even writable, which is all expected. Why do you think it does not exists when you see it actually does? – Progman Nov 01 '20 at 13:19
  • Because right after the function call, I execute `ls /tmp` and it doesn't have the said files – Saqib Ahmed Nov 01 '20 at 13:20
  • Do you have any mechanism that can change the filesystem like docker, chroot, etc? – shingo Nov 01 '20 at 13:22
  • @shingo I'm not running docker. I can do chroot if that's what you mean – Saqib Ahmed Nov 01 '20 at 13:23
  • 1
    @SaqibAhmed Please [edit] your question to include how you execute the php script and how you run the `ls /tmp` command. Even add a `shell_exec('ls /tmp');` to your php script. Include the output of both the php script and the `ls` command to your question, both from the `shell_exec()` line as well from the command line. – Progman Nov 01 '20 at 13:25
  • @Progman Now you're on to something. The outputs are different. – Saqib Ahmed Nov 01 '20 at 13:31
  • Updated the details in the question – Saqib Ahmed Nov 01 '20 at 13:32
  • @SaqibAhmed Please [edit] your question to include the output of `stat /tmp` executed from the PHP script and executed from the command line. And for that matter, do it the same for `stat /`. – Progman Nov 01 '20 at 13:48
  • @Progman Updated the question with the commands you mentioned. – Saqib Ahmed Nov 01 '20 at 18:12
  • @SaqibAhmed As you see by the "inode" value for the `stat /tmp` entries, the path `/tmp` is not referencing the same object in the file system, seen from the PHP script and from the command line. Ask the server administrator how the web server is set up, what security features are in place and what the server configuration is. – Progman Nov 01 '20 at 18:15
  • Yes I can see that. But that's really weird. Never seen such a problem before. Thank you so much for helping me debug it. Wouldn't have been able to troubleshoot without your help. – Saqib Ahmed Nov 01 '20 at 18:17
  • 1
    @Progman I have provided the debugging details. Can you mark this question open now? – Saqib Ahmed Nov 01 '20 at 18:19

0 Answers0