8000 [Process] Permission Denied writing to sf_proc_00.out.lock when file is generated by a different AppPoolIdentity User · Issue #37294 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Process] Permission Denied writing to sf_proc_00.out.lock when file is generated by a different AppPoolIdentity User #37294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JasonStephensTAMU opened this issue Jun 15, 2020 · 0 comments

Comments

@JasonStephensTAMU
Copy link
Contributor

Symfony version(s) affected: 4.4.8|5.1.2

  • OS: Windows 10
  • Server: IIS version 10
  • PHP version 7.3
  • Laravel version 6.18

Note: Bug originally encountered on Laravel 6.18 using symfony/process 4.4.8. I have replicated the issue on a fresh symfony/skeleton 5.1.2 base with the process package required through composer.

Description

When two or more sites are running IIS / FastCGI as different AppPoolIdentity users with limited group permissions to the sys_temp_dir, the first to write sf_proc_00.* files used by the Process class takes ownership, however any additional sites that attempt to write to this file will receive the following error:

A temporary file could not be opened to write the process output: fopen(C:\WINDOWS\TEMP\sf_proc_00.out.lock): failed to open stream: Permission denied

Our permissions are configured to prevent one site from modifying temporary files that are created by another.

How to reproduce

  1. In IIS: Add two sites using the Symfony\Process component with different Application Pools
  2. In IIS Application Pools: For both application pools used, select "Advanced Settings" and confirm the "Identity" field is set to the built-in "ApplicationPoolIdentity" account,
  3. In IIS Feature Panel: For both sites, select "Authentication" > "Anonymous Authentication", ensure it is enabled and click "Edit..." then select "Application Pool Identity" and click OK.
  4. Set limited permissions for the IIS_IUSRS group on the sys_temp_dir (this is C:\Windows\Temp on my machine). Verify the Users group does not exceed these permissions.
    • Permissions used in testing: List folder / read data, Read attributes, Read extended attributes, Create files / write data, Read permissions
  5. For both sites, create some code that uses the Process class to run a command. (See Additional Context for the sample code I used to test)
  6. In Site A, run the code using the Process class and check the sys_temp_dir to confirm sf_proc_00 files were generated.
  7. In Site B, attempt to run the code using the Process class to throw the Permission Denied error.

Possible Solution

Perhaps a solution could be incrementing the filename when the lock files exist, but cannot be opened for writing, and removing the sf_proc_## files used in the WindowsPipes destructor.

I have limited experience in using the Process class, I'll post the code that has fixed it in my particular instance, however I do not know if it is ideal for all use cases.

symfony\process\Pipes\WindowsPipes.php, Line 58: (Try next iteration if lock file exists)

                    if (!$h = fopen($file.'.lock', 'w')) {
                        if (file_exists($file.'.lock'))
                            continue 2;

                        restore_error_handler();
                        throw new RuntimeException('A temporary file could not be opened to write the process output: '.$lastError);
                    }

symfony\process\Pipes\WindowsPipes.php, Line 88: (Remove files on destruct)

    public function __destruct()
    {
        $this->close();

        foreach ($this->files as $file) {
            unlink($file);
            unlink($file.'.lock');
        }
    }

Additional context

During replication, I made a simple controller that dumps output of the dir command for testing:

src\Controller\HomeController.php:

<?php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;

class HomeController
{
    public function index()
    {
        $process = new Process(['dir']);
        $process->run();

        if(!$process->isSuccessful())
            throw new ProcessFailedException($process);

        return new Response($process->getOutput());
    }
}

And attached it to the base route:

config\routes.yaml:

index:
    path: /
    controller: App\Controller\HomeController::index

The same code was used on both Site A and B.

@xabbuh xabbuh added the Process label Jun 16, 2020
nicolas-grekas added a commit that referenced this issue Jul 6, 2020
…_00 lock files on Windows (JasonStephensTAMU)

This PR was merged into the 3.4 branch.

Discussion
----------

[Process] Fix Permission Denied error when writing sf_proc_00 lock files on Windows

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | yes
| New feature?  |no
| Deprecations? | no
| Tickets       | Fix #37294
| License       | MIT
| Doc PR        |

Passes current Process unit tests.

On Windows systems, a new set of sf_proc_## files are generated in the system temp directory for each WindowsPipes object. These files are removed when the WindowsPipes object is destroyed.

This avoids receiving a permission denied error when attempting to write to sf_proc_## files between multiple sites running as different users, when the users do not have permissions to modify each others files.

Changes
- [Process] WindowsPipes always creates new sf_proc_## files in constructor
- [Process] WindowsPipes removes its sf_proc_## files in destructor

Commits
-------

220be89 [Process] Fix Permission Denied error when writing sf_proc_00 lock files on Windows
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants
0