microsoft / WSL

Issues found on WSL
https://docs.microsoft.com/windows/wsl
MIT License
17.25k stars 812 forks source link

bash $PATH includes native Windows path entries #1640

Closed markgross closed 7 years ago

markgross commented 7 years ago

I see that my Anaconda3 (a windows python distrobution) has executibles on the bash path. I expected only linux native programs to be accessible from the ubuntu bash env.

mgross@marks-x1:~$ which fetch_file.exe /mnt/c/Program Files/Anaconda3/Scripts/fetch_file.exe mgross@marks-x1:~$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/Windows/System32:/mnt/c/Windows:/mnt/c/Windows/System32/wbem:/mnt/c/Windows/System32/WindowsPowerShell/v1.0:/mnt/c/Program Files/Anaconda3:/mnt/c/Program Files/Anaconda3/Scripts:/mnt/c/Program Files/Anaconda3/Library/bin:/mnt/c/Users/mark9/AppData/Local/Microsoft/WindowsApp

I worry that the leakage of the Windows environment into the bash will result in unexpected behaviors from time to time.

Gabrielcarvfer commented 7 years ago

@markgross people asked in UserVoice to be able to run Windows commands from bash, so it should be a feature. As it is appended to the PATH, it shouldn't make any difference if you have python or any other linux programs installed on WSL. If you don't want that to happen, just export PATH containing only WSL folders on ~/.bashrc . :)

MikeGitb commented 7 years ago

@Gabrielcarvfer: It makes a difference if you have installed a tool in Windows but not in linux. Usually you'd get an error like "tool XY is currently not installed. Type sudo apt install ... to install it now". If the windows version gets picked up instead, everything works either as expected or you might get very strange errors. However, I'd expect this to be a rather rare occasion.

markgross commented 7 years ago

Default options should be secure options. If someone wants to add power shell env path's to their bash env they can so. But, adding things by default is IMO a problem that will bite people in the future.

Also, I don't want any python scripts or executable leaking between my windows and linux environments.

Gabrielcarvfer commented 7 years ago

@MikeGitb and @markgross , a switch for that in Settings's Developer section for that (injecting Windows path on WSL path) would solve your problem, but this is a work in progress, in a prerelease build, then you can use the workaround until they fix it.

aseering commented 7 years ago

@markgross -- to answer your implied initial question, this is a deliberate feature.

Regarding your concern about namespace collisions -- note that Windows executables must have a file extension such as .exe, .com, etc. As you've seen above, you can find fetch_file.exe, but you must then execute it as fetch_file.exe, not fetch_file. In contrast, by convention Linux executables in $PATH typically do not have file extensions. As a result, names will tend to not conflict too often. You are, of course, absolutely correct that they can conflict.

Regarding security -- my expectation right now as a user is that any malicious WSL process can acquire Linux root at any time. If you've already got root, messing with stuff in $PATH is small potatoes :-) WSL processes (even ones running as root) are all just unprivileged (as far as Windows is concerned) programs running under your Windows user account. So the environment is effectively single-user, and should IMO be secured accordingly. (The WSL team is probably looking into more-sophisticated security models, but that's what exists today, as far as I can tell.)

Regarding controlling this behavior, take a look at #1493 .

itomkins commented 7 years ago

On my system the bash path is truncated for some reason I can't figure: $ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mnt/c/ProgramData/Oracle/Java/javapath_target_4529046:/mnt/c/Windows/System32:/mnt/c/Windows:/mnt/c/Windows/System32/wbem <SNIP> :/mnt/c/Program Files/Oracle/VirtualBox:/mnt/c/Program Files (x86)/Nma

Where the original Windows path ends with ;C:\Program Files (x86)\Nmap

Also for some reason the .profile is not adding my ~/bin directory to the path, I have copied the relevant code to the end of .bashrc and it works fine so not sure what is going on there

benhillis commented 7 years ago

I agree with @aseering. Since you have also provide the file extension to invoke the Windows binaries I think it is pretty unlikely that there will be much confusion. @markgross if you have a specific case where this is happening kindly reopen this ticket.

You can disable this feature by setting this registry key:

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss]
"AppendNtPath"=dword:00000000

@itomkins - I assume you're running an older insider build? There was an off by one error that is fixed in recent builds.

aseering commented 7 years ago

@itomkins -- regarding .profile, that might be an instance of #816 ?

benhillis commented 7 years ago

@aseering - yes it is.

itomkins commented 7 years ago

Thanks @benhillis @aseering correct on both points, added --login to shortcut and will have to switch from slow to fast to pick up a newer build i guess.

markgross commented 7 years ago

I just watched some videos from https://blogs.msdn.microsoft.com/commandline/learn-about-bash-on-windows-subsystem-for-linux/

Specifically https://sec.ch9.ms/ch9/ed3c/e3560e79-4719-49dc-a7e8-607ca516ed3c/WindowSubsystemforLinuxFileSystem_high.mp4

around time stamp 22min it talks about the effects of native windows programs operating on WSL files. It results in files that can't be seen from the bash environment.

Please explain why allowing windows path's is a good idea? It looks like a train wreck given this new information.

markgross commented 7 years ago

Hmm, I guess there is one more video I needed to watch before posting my last comment. https://blogs.msdn.microsoft.com/wsl/2016/10/19/windows-and-ubuntu-interoperability/

Still, if I do the following I get a bad experiance: 1) from bash vim $HOME/temp.txt and add some text. 2)close vim. 3) open gvim.exe (windows gvim install) gvim.exe $HOME/temp.txt

I can't edit the content I added and I can't save anychanges I made over top temp.txt

aseering commented 7 years ago

Hi @markgross -- have you actually tried running the command that you suggest? I think you will find that the set of things that you can't do is larger than you are saying :-)

benhillis commented 7 years ago

@markgross - Due to the filesystem limitations you mention above accessing files in LxFs (anything not under /mnt/*) is not supported via interop. You won't be able to modify files in LxFs unless you do some trickery like passing the full NT path of .bashrc to gvim.exe.

I'd suggest trying out the feature and seeing how it works. I'd love to hear specific feedback about things that aren't working as you expect. As long as you're working out of one of your mounted NTFS drives you shouldn't run into issues.

As an aside: the limitation of not being able to modify files in LxFs is something we're spending a lot of time looking at for a future release. I would love to come up with a solution that gets rid of this limitation - but creating a mapping between Linux and NT security models is a complicated problem. Just ask anybody who's worked on samba :)

markgross commented 7 years ago

Thanks. I will think some more about the VSF/NTFS issues for content not under /mnt/[a..z].

FWIW I have not done any powershell based development so a lot of the utility for this feature is lost on me. but, I do work in linux on native Linux boxes. Yes, those mappings are not simple to deal with. they are so complex I would punt on it.

Understanding the use case after watching your interview helps. I'm still not sure its worth the native linux file inconsistencies that happen because of having this feature. ok, I don't think its worth it because of the LxFs / NTFS extended attributes (and caching) issues. but, I agree its handy when operating on NTFS files under /mnt/[a..z] somewhere and wanting to use native linux user mode tools.

FWIW I'd hide the extended path from the normally launched bash shell but enable it from powershell command line invocations of base.exe if I couldn't address the LxFs / NTFS issues enough for a good UX. But, the user needs to be aware of the file system limitations.

Thanks for the responses! I've been very impressed with the direct interaction with you developers on WLS.

irontoby commented 6 years ago

Not sure where the idea that "since you have to also provide the file extension to invoke the Windows binaries I think it is pretty unlikely that there will be much confusion" is coming from. Perhaps this helps illustrate the problem:

Me on any other Ubuntu system:

toby@localhost:~$ npm -v
The program 'npm' is currently not installed. You can install it by typing:
sudo apt install npm
toby@localhost:~$ sudo apt install npm

It's a super-helpful feature and incredibly streamlined workflow. I don't even worry about whether some CLI snippet I see online needs a tool I don't have. I just paste it and if something is missing, Bash tells me exactly how to get it.

Me using Ubuntu bash on Windows:

toby@localhost:~$ npm -v
: not foundram Files/nodejs/npm: 3: /mnt/c/Program Files/nodejs/npm:
: not foundram Files/nodejs/npm: 5: /mnt/c/Program Files/nodejs/npm:
/mnt/c/Program Files/nodejs/npm: 6: /mnt/c/Program Files/nodejs/npm: Syntax error: word unexpected (expecting "in")
toby@localhost:~$

Incredibly unhelpful, and not a very good experience for those who are used to Linux and expect the WSL environment to be more "clean". I didn't type any Windows extension anywhere for this to happen. I think the intersection of people who have node.js installed on Windows and want a completely separate node.js in WSL would be quite high.

Very glad to see the regedit entry to solve this, but exposing it more visibly would be quite welcome. At any rate, thanks for listening, I'm very much enjoying WSL so far...

oterhals commented 6 years ago

Here's another workaround, although not the most elegant one.

If you add this to the end of your .bashrc file, all references to Windows PATHs will be removed. In my case 20 elements are removed and only 8 are left:

PATH=$(/usr/bin/printenv PATH | /usr/bin/perl -ne 'print join(":", grep { !/\/mnt\/[a-z]/ } split(/:/));')

Not sure if this will catch everything, but it does the trick for me.

markgross commented 6 years ago

FWIW I just changed my PATH to be what it should be in the bashrc file. similar to what you have just without the perl magic.

On Sun, Oct 8, 2017 at 1:04 PM, oterhals notifications@github.com wrote:

Here's another workaround, although not the most elegant one.

If you add this to the end of your .bashrc file, all references to Windows PATHs will be removed. In my case 20 elements are removed and only 8 are left:

PATH=$(/usr/bin/printenv PATH | /usr/bin/perl -ne 'print join(":", grep { !/\/mnt\/[a-z]/ } split(/:/));')

Not sure if this will catch everything, but it does the trick for me.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Microsoft/BashOnWindows/issues/1640#issuecomment-335034046, or mute the thread https://github.com/notifications/unsubscribe-auth/AADz5OnC7OybBxRWkwq8-afI4cfHFmJQks5sqSq5gaJpZM4LwlT1 .

-- create interesting things.

zbutfly commented 6 years ago

I write a script to resolve it, append . scriptname.sh at your ~/.profile or any other init script else:

#!/bin/bash

IFS=':'
NEWPATH=''

for p in ${PATH[@]}
do
    if [ "${p:0:5}" != "/mnt/" ]; then
        NEWPATH+=":$p"
    fi
done
IFS=' '

export PATH=${NEWPATH:1}
mpiroc commented 6 years ago

The rationale for closing this bug is that "you need to include the file extension in order to invoke windows executables". But as @irontoby demonstrated (I see the same behavior on my system), this just isn't true. If you invoke foo, Windows considers foo.exe to be a match.

Even with nodejs installed through apt-get, running node still picks up the Windows version, not the Linux version.

I don't believe that this bug should be closed.

benhillis commented 6 years ago

@mpiroc - That's because the node guys removed the .exe extension from their binary.

mpiroc commented 6 years ago

@benhillis On my machine, it's still present:

pirocchi@LAPTOP:/mnt/c/repos/foo$ whereis node
node: /mnt/c/Program Files/nodejs/node.exe
benhillis commented 6 years ago

@mpiroc - Look in that directory, you'll also find a "node" file with no extension.

mpiroc commented 6 years ago
pirocchi@LAPTOP:/mnt/c/repos$ ls "/mnt/c/Program Files/nodejs/"
node_etw_provider.man  node.exe  node_modules  node_perfctr_provider.man  nodevars.bat  npm  npm.cmd  npx  npx.cmd
mpiroc commented 6 years ago

I verified by downloading from https://nodejs.org/en/download/. As of the current LTS release (8.11.2), the .exe extension is still present on Windows, and no additional node file without the extension is present.

mpiroc commented 6 years ago

@benhillis

benhillis commented 6 years ago

@mpiroc - That is not the behavior I am seeing:

image

wlerin commented 6 years ago

@mpiroc The example earlier calls npm, not node. npm without an .exe is present in your screenshot.

That said, this "feature" mostly just adds meaningless noise, especially to path completions since most files on NT filesystems have their executable bits "set" (or at least bash thinks they do).

rainabba commented 6 years ago

Going to pipe in here also. The ONLY reason I care about WSL was so I could do node.js and Docker development on my Windows workstation. I realize this was an "intentional feature" to cater to people with undisciplined environments where they can chance such things, but are those the people you want to be selecting feature for given the reason (and the only way) that WSL is so demanded (Windows developers wanting full posix environments). WE are impacted negatively by this behavior and the defense is just plain silly, especially in light of this.

When I have to waste time, un-breaking a default setup, something is wrong. NPM is a worse-case offender too because they did as they should have, and stuck with extensionless executables (as it wasn't needed), but NPM is core to why I even want WSL.

rainabba commented 6 years ago

Thanks to Rich Turner on Twitter: https://twitter.com/richturn_ms/status/1019452175523577856?s=19

This should address the issue nicely though I haven't confirmed myself just yet:

https://blogs.msdn.microsoft.com/commandline/2018/02/07/automatically-configuring-wsl/

mhamrah commented 6 years ago

I'm curious how people about being able to execute Linux commands via wsl natively from Windows? I'd love for something like VS Code on WIndows to pick up the Linux version of node. I know this was demo'ed as a special case by passing the node command and parameters via the wsl.exe command on the Windows site, but without having Linux PATH support from windows, you have to create a wrapper command for every Linux command you want to expose. Really annoying when it comes to NPM (and Go). Even though these are supported natively on Windows, having the Linux ecosystem and Linux binaries run 'natively' on Windows is a huge benefit for development.

benhillis commented 6 years ago

You can prefix any Linux command you want to run with "wsl" for example: 'wsl ls'

mhamrah commented 6 years ago

Correct, but I want Windows to automatically prepend 'wsl' based on any commands it finds in my path that are in linux via WSL. This will let things like extensions in vs code call out to 'npm' and have it run the linux version.

therealkenc commented 6 years ago

prepend 'wsl' based on any commands it finds in my path that are in linux via WSL

That's #1823

mean-ui-thread commented 6 years ago

~I got the same kind of issues than most people here: It picks the ruby from Windows 10 instead of /usr/bin/ruby from Linux, it picks npm from Windows 10 instead of /usr/bin/npm from Linux, it picks perl from Windows 10 instead of /usr/bin/perl from linux, etc. And these are causing all kinds very weird and strange error messages and weird behaviours on my side.~

~To fix it, I just added these two lines in my ~/.profile file:~

unset PATH
. /etc/environment

~and all of the problems when away:~

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

~No more Windows 10 Paths in my linux's PATH environment variable.~

EDIT 2019-05-17

@m00head 's comment next to mine is the best workaround since it doesn't involve hacking anything in your bash profile: https://github.com/microsoft/WSL/issues/1493#issuecomment-417639271

regedit here:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss\{GUID}\Flags

Change Flags from 7 to 5. That's it!

Now my path looks like this:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
m00head commented 6 years ago

I have posted the latest workaround for this issue here: https://github.com/Microsoft/WSL/issues/1493#issuecomment-417639271

c0ze commented 5 years ago

@markgross -- to answer your implied initial question, this is a deliberate feature.

this is a horrible call of judgement and I am apalled this has not been fixed yet.

this should not be on by default. It should be other way around.

Vichoko commented 5 years ago

As the windows paths are added to the tail of PATH, it have preference. I got colissions of names with python (as it's called without extension in both systems), also pip didn't work even that i'm sure it was installed in both windows and linux. @oterhals solution worked perfectly, as i prefer having isolated enviroments between both systems

DavidKDeutsch commented 5 years ago

A note to those that have stumbled upon this thread via searching: forget the registry tweaks mentioned here and elsewhere, as they keep changing. I used the method mentioned in #1493 and it worked like a charm:

echo "export PATH=`echo $PATH | tr ':' '\n' | grep -v /mnt/ | tr '\n' ':'`" >> ~/.bashrc

I'm sure @mchiasson's solution, @oterhals solution, etc. work as well; the benefit of any of these methods is that since the changes are within the WSL environment itself, the fix will survive whatever Microsoft decides to "tweak" later on.

And for the record, add me to the list of people who are baffled that this "feature" is enabled by default. It's not a lot of fun trying to diagnose errors such as : not foundram Files/nodejs/npm....

newtonmunene99 commented 5 years ago

@DavidKDeutsch Thank you so much. You are a life saver

mean-ui-thread commented 5 years ago

@m00head 's workaround is the best one so far : https://github.com/microsoft/WSL/issues/1493#issuecomment-417639271

gnarus-io commented 4 years ago

Fix at #1493 fixes this flutter error for anyone landing here from google.

~/sdks/flutter$ flutter upgrade
/mnt/c/Users/GavinShaw/.flutter/bin/flutter: line 5: $'\r': command not found
/mnt/c/Users/GavinShaw/.flutter/bin/flutter: line 6: $'\r': command not found
/mnt/c/Users/GavinShaw/.flutter/bin/flutter: line 14: $'\r': command not found
LachlanArthur commented 4 years ago

Instead of trying to fiddle with the path or the registry, just disable the feature.

in WSL:

sudo vi /etc/wsl.conf

add:

[interop]
appendWindowsPath = false

then in Windows find your distro name and terminate it so the config changes are picked up:

wsl.exe --list
wsl.exe --terminate <distro_name>

wsl.conf options

wlerin commented 4 years ago

That option was added long after this issue was closed, and is mentioned in #1493 , but still helpful to document it here as well I guess.

mattwelke commented 3 years ago

The approach to edit sudo vi /etc/wsl.conf and add:

[interop]
appendWindowsPath = false

solved this problem for me. I no longer have Windows executables on my path. But it changed how I have to start VS Code with WSL now. Just thought I'd mention it in case someone else googles it and ends up here.

I used to be able to start VS Code for Remote WSL work by typing code <dir_name> in WSL, but that was the Windows binary it was launching before.

So now, since VS Code can't be started from within WSL, start open VS Code in Windows (with the remote extension installed) and use the command palette (because the option doesn't show up in the GUI) menu to select Remote-WSL: New Window if your VS Code didn't start in WSL mode when you opened it:

image

Then, Open Folder..., which will show you folders within your WSL distro.

giraffesyo commented 3 years ago

@mattwelke To solve that problem you can include the Windows installation of vs code in your path explicitly,

e.g.

echo PATH=\$PATH:/mnt/c/Users/`whoami`/AppData/Local/Programs/Microsoft\\ VS\\ Code/bin >> ~/.bash_profile
therealkenc commented 3 years ago

Quoted rather than escaped is probably more straightforward, and that leading backslash doesn't look right, and your WSL username is not necessarily your Windows username.

This said, cherry picking Windows paths in .bashrc is not a bad way to roll in some circumstances.

mattwelke commented 3 years ago

This said, cherry picking Windows paths in .bashrc is not a bad way to roll in some circumstances.

Would this be an effective way to limit access to Windows executables to just VS Code (or some other program) while keeping Windows binary interop turned on? For example, to prevent node within WSL from picking up Node.js installed in Windows?

giraffesyo commented 3 years ago

Quoted rather than escaped is probably more straightforward, and that leading backslash doesn't look right, and your WSL username is not necessarily your Windows username.

This said, cherry picking Windows paths in .bashrc is not a bad way to roll in some circumstances.

That's true that the username doesn't have to match, good call.

As for the leading backslash, thats because it would expand your current path if you didn't do that.

gioreva commented 3 years ago

@Gabrielcarvfer

If you don't want that to happen, just export PATH containing only WSL folders on ~/.bashrc . :)

My ~/.bashrc does not contain Windows PATH. And I can't find any other files, I need to remove them.

WSL2 Ubuntu