Reputation: 141
I have a program that only works on Linux, and I have my development environment on Windows.
When I run a WSL command from cmd
in Windows it works as expected.
C:\wsl echo "foo"
in cmd.exe
I get foo
back via stdout.When I run the same command from within php via exec
I don't get any stdout output and get an exit code -1073740791
which I assume is an error.
Cmd.exe:
C:\wsl echo "foo"
foo
PHP:
<?php
$cmd = 'wsl echo "foo"';
exec($cmd, $out, $code);
dd($out, $code);
?>
// $out is []
// $code is -1073740791
Upvotes: 2
Views: 1427
Reputation: 776
Summarizing Dai's answer;
You are probably running Apache as NT Authority\SYSTEM (aka Local System or LocalSystem), and WSL doesn't like to run as anything but your user (And its also a bad security practice)
A simple fix, at least for WSL's issues, is to change the service's properties to use your windows user, on services.msc
, wampstackApache
(or similar), log on
.
echo shell_exec("whoami");
will then report your user correctly and WSL will run just fine.
Disclaimer; I dont know how bad of a security issue this is, but it sounds kinda bad
Upvotes: 0
Reputation: 154995
As discussed in the comments, the underlying issue was that your systemwide Apache web-server service (wampapache64
) was configured to run as NT Authority\SYSTEM
(aka Local System
or LocalSystem
).
...and running anything like a web-server as LocalSystem
is a very, very bad idea for other reasons, especially when it's running PHP code - a simple mistake in uploaded-file handling or a failure to correctly sanitize user input could potentially hose your entire computer, especially when it's a publicly-exposed web-server that a malicious attacker can connect to.
Anyway:
Apparently when a process is running as SYSTEM
it cannot use Win32's CreateProcess
to invoke wsl
to then indirectly invoke a Linux program.
PHP's exec
function is implemented like so:
exec
function wraps PHP's internal VCWD_POPEN
.VCWD_POPEN
is a macro defined as #define VCWD_POPEN(command, type) virtual_popen(command, type)
virtual_popen
varies based on OS:
virtual_popen
simply invokes popen_ex(command, type, CWDG(cwd).cwd, NULL)
.
popen_ex
calls CreateProcessAsUserW
or CreateProcessW
to actually start the new process.popen_ex
uses OpenThreadToken
to ensure the new process is created with the same user-account and permissions as the parent process - in this case NT Authority\SYSTEM
.So PHP's exec()
is not just a simple wrapper over C's system()
.
Whereas if exec()
was a wrapper over system()
then programs would be invoked via cmd.exe
which will behave differently (though that too would likely fail as well)
So by changing your web-server to run as a real user account that meant that the CreateProcess...
call invoked wsl
within a supported environment.
Upvotes: 2