[Process] Permission Denied writing to sf_proc_00.out.lock when file is generated by a different AppPoolIdentity User · Issue #37294 · symfony/symfony · GitHub
You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
8000
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
In IIS: Add two sites using the Symfony\Process component with different Application Pools
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,
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.
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
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)
In Site A, run the code using the Process class and check the sys_temp_dir to confirm sf_proc_00 files were generated.
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'))
continue2;
restore_error_handler();
thrownewRuntimeException('A temporary file could not be opened to write the process output: '.$lastError);
}
symfony\process\Pipes\WindowsPipes.php, Line 88: (Remove files on destruct)
…_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
Symfony version(s) affected: 4.4.8|5.1.2
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
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)
symfony\process\Pipes\WindowsPipes.php, Line 88: (Remove files on destruct)
Additional context
During replication, I made a simple controller that dumps output of the
dir
command for testing:src\Controller\HomeController.php:
And attached it to the base route:
config\routes.yaml:
The same code was used on both Site A and B.
The text was updated successfully, but these errors were encountered: