Skip to content
New issue

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

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

Already on GitHub? # to your account

Issues with env -i #426

Open
ale5000-git opened this issue Jun 19, 2024 · 8 comments
Open

Issues with env -i #426

ale5000-git opened this issue Jun 19, 2024 · 8 comments

Comments

@ale5000-git
Copy link

ale5000-git commented Jun 19, 2024

I'm not sure if I'm doing something wrong but this fail:
env -i ./mytest.bat

The error is:
env: can't execute './mytest.bat': Invalid argument

The content of ./mytest.bat file is just echo "Abc".


Also when using env -i a default PATH var is reestablished but this PATH var is not exported, is it supposed to be like this?

@rmyorston
Copy link
Owner

I've found two workarounds for the first problem:

env -i COMSPEC="$COMSPEC" ./mytest.bat
env -i SYSTEMROOT="$SYSTEMROOT ./mytest.bat

The resulting environment is as empty as it can be and still have batch files work. Details below.

How are you determining there's a default PATH with env -i? I'm not sure there is.

The details

Regarding the first problem: it doesn't require the entire environment to be cleared; it can also be seen with env -u COMSPEC -u SYSTEMROOT.

Those two environment variables are special: they're the ones that must have backslashes in their values, or bad things can happen. They're used by Windows when it needs to know how to run cmd.exe.

They both have to be unset for the problem to arise. If only COMSPEC is unset the call to spawnve() in win32/process.c succeeds, but with ERROR_ENVVAR_NOT_FOUND. When both are unset spawnve() fails with ERROR_DIRECTORY. This seems to suggest that if Windows can't find the environment variable COMSPEC it carries on by building a likely path using SYSTEMROOT, but if that can't be found it gives up.

Trying something else. This works:

unset COMSPEC SYSTEMROOT
./mytest.bat

Why the difference? What I think is going on:

In the case of the shell it's only the shell variables that are unset. The real environment is still present. When the shell comes to run ./mytest.bat a temporary environment is created from the shell variables and passed to the child process. When Windows tries to run cmd.exe to execute the batch file it can't find the environment variables it needs in the temporary environment so it looks in the real one (by accessing the global environ). That works, and indeed COMSPEC and SYSTEMROOT are both available in the batch script.

In the case of env the real environment is altered, so there isn't anything for Windows to fall back to. The workarounds restore just enough of the environment for it to work out how to run cmd.exe.

@rmyorston
Copy link
Owner

The shell has a PATH shell variable which isn't exported. It exports SHLVL and PWD. Support for globbing in busybox-w32 uses the BB_GLOBBING variable.

The environment created by env -i is empty, but the command it runs may set variables.

~ $ env -i env
BB_GLOBBING=0
~ $
~ $ env -i sh -c env
SHLVL=1
BB_GLOBBING=0
PWD=C:/Users/rmy
~ $
~ $ env -i sh -c 'echo $PATH'
C:/Windows/System32;C:/Windows

@ale5000-git
Copy link
Author

ale5000-git commented Jun 20, 2024

How are you determining there's a default PATH with env -i? I'm not sure there is.

With this I see that there is a default path:
env -i sh -c 'set'

Instead with this I see that it isn't exported:
env -i sh -c 'env'

PS: I have seen that it is the same on bash online so probably this is correct but still it would be nice to have the batch execution working.


Isn't possible to set a default SYSTEMROOT near the code that set the default PATH?
I said SYSTEMROOT because it should be easier to set compared to COMSPEC.
This would allow to use env -i without breaking bath execution.

@avih
Copy link
Contributor

avih commented Jun 20, 2024

Isn't possible to set...

Sure it's possible, but the question is whether that would be a good thing.

env -i is supposed to set the env exactly to the args. From POSIX:

env -i: Invoke utility with exactly the environment specified by the arguments; the inherited environment shall be ignored completely.

You should know what you're doing when you clean the environment, and part of that knowledge is knowing what you should preserve for your needs.

@ale5000-git
Copy link
Author

ale5000-git commented Jun 20, 2024

You should know what you're doing when you clean the environment, and part of that knowledge is knowing what you should preserve for your needs.

Yes, but on Linux it set a default PATH otherwise everything will break (for example mktemp).
On Linux it is able to execute shell files.
On Windows there are batch files that aren't present on Linux, and it would nice to be able to execute them without workarounds.

Put the case that a code is like this:
env -i ./MY_FILE

And 2 files:
./MY_FILE (shell)
./MY_FILE.bat (batch)

This code would execute the shell file on Linux but break on Windows.

PS: Maybe the SYSTEMROOT could be made to be available to batch files but not exported to shell.

@avih
Copy link
Contributor

avih commented Jun 20, 2024

Yes, but on Linux it set a default PATH

Don't know who's "it", but env and bash and dash don't:

$ env -i env  # empty output

$ env -i sh -c export  # dash
export PWD='/<whatever PWD was originally>'

$ env -i bash -c export
declare -x OLDPWD
declare -x PWD="/<whatever PWD was originally>"
declare -x SHLVL="1"

@ale5000-git
Copy link
Author

ale5000-git commented Jun 20, 2024

Yes, but on Linux it set a default PATH

Don't know who's "it", but env and bash and dash don't:

$ env -i env  # empty output

$ env -i sh -c export  # dash
export PWD='/<whatever PWD was originally>'

$ env -i bash -c export
declare -x OLDPWD
declare -x PWD="/<whatever PWD was originally>"
declare -x SHLVL="1"

They set a default "NOT exported" PATH, try this:
env -i bash -c 'set'

@rmyorston
Copy link
Owner

The issue with env -i and batch files is a specific example of a general problem: any tampering with COMSPEC and SYSTEMROOT may result in batch files failing to run.

I don't think it's practical for busybox-w32 to detect and warn about such problems, much less mitigate them.

Consider:

  • Unsetting the variables isn't the only issue: setting them to empty or otherwise invalid values will also result in failure.
  • Since the environment is inherited by child processes the failure may occur in some unrelated, non-BusyBox process.

Anything done in env or even at a lower level in spawnveq() can only be a partial solution. So I'm inclined not to make the attempt.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants