file_put_contents returns alright, but no file is created

Viewed 337

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.

0 Answers
Related