-
Notifications
You must be signed in to change notification settings - Fork 281
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
Prevent EPERM error hit when trying to open installer.exe #1855
Conversation
This prevents us from having to run commands twice to get the status and stdout. Caution must be taken to make sure that the assumptions here in what is returned as stdout vs stderr are correct. Furthermore, when looking at the code, I saw something that looked just plain incorrect, so I will need to investigate that by adding the TODO before merge
vscode-dotnet-runtime-library/src/Acquisition/GenericDistroSDKProvider.ts
Outdated
Show resolved
Hide resolved
vscode-dotnet-runtime-library/src/Acquisition/GenericDistroSDKProvider.ts
Outdated
Show resolved
Hide resolved
…de-dotnet-runtime into nagilson-fix-eperm
export function InstallToStrings(key: DotnetInstall | null) { | ||
if (!key) { | ||
return { installKey: '', version: '', architecture: '', isGlobal: '', installMode: '' }; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I believe the convention for TS is to have the curly braces at the end of the line, like what was here previously. Scripting languages tend to follow that convention (JS, TS, etc.) while C-style languages put it in a new line by itself. But I understand you're changing it to be consistent with everything else in this repo. I believe there is an .editorconfig setting to can enable to do this for you automatically.
A similar inconsistency I see is if (
vs if(
. But I don't know which is more stylistically the convention for TS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a great point. EditorConfig
is pretty awesome, but the javascript and typescript settings appear to be less standardized than the C# and .NET settings for brackets. Anywho, I will make that config file in another PR upcoming soon :)
That is the convention, but I disagree with the convention. I always think about apples SSL bug https://www.codecentric.de/wissens-hub/blog/curly-braces#:~:text=To%20sum%20up%20the%20debacle,To%20say%20the%20least. and that is a large part of my reasoning for my opinion here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally, learning to read/write in the conventions of another language is very useful and transferrable. I tried to write in a C#-style in ColdFusion and it didn't work whatsoever. Not just stylistically, but conceptually. But TS is pretty loose on this particular convention. However, any TS I've worked on always had the curly braces at the end of the line, to match the JavaScipt style.
|
||
if(os.platform() === 'win32') // Windows does not have chmod +x ability with nodejs. | ||
{ | ||
const commandRes = await this.commandRunner.execute(CommandExecutor.makeCommand('icacls', ['/grant', `"${installerPath}"`, `"%username%":F`, '/t', '/c']), null, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What permissions does node need to run icacls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a very good question.
I did some digging, the internet seems to suggest you need administrator rights to run icalcs
. That makes sense. But I just tried to do it without admin rights on a local user file without administrator rights and it also worked. It did not work on a non-user-local file. This also makes sense, so it appears the final answer is that it's scoped similarly to areas on disk that are already writeable to.
This is being run by a sub-process of vscode, which should have the same privileges as vscode. If it is an admin it is not a concern. If it is not admin it should be running under the user account. The file its trying to add +x to is also a user local file, so my understanding is that it should function properly and be permitted.
Unfortunately we dont have any actual customer reports of EPERM issues, just that its showing up in our error data. I think either way though, if this does not work, the primary option we have is just to ask for elevation right away.
|
||
if(os.platform() === 'win32') // Windows does not have chmod +x ability with nodejs. | ||
{ | ||
const commandRes = await this.commandRunner.execute(CommandExecutor.makeCommand('icacls', ['/grant', `"${installerPath}"`, `"%username%":F`, '/t', '/c']), null, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are these parameters ordered? According to https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/icacls#syntax the syntax should be icacls <filename> [/grant[:r] <sid>:<perm>[...]]
Also note that because you're not using grant:r
you will be adding and retaining existing perms, which is different from the explicit 744 that chmod is doing. Also, should the chmod be moved into a separate if
for non-windows and then explicitly set the ACL.
Can you share the results of this? Run the code, then from Powershell, run Get-Acl <path-to-filename> | Select-Object -ExpandProperty Access
and just strip out any PII before pasting in it (or ping me offline).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, that's a good point. It was working for me with this ordering, but I will fix the ordering.
I will also condition the chmod. It has a side-effect of allowing us to change the write permissions, but I suppose if icacl works then it doesn't need to be called.
ACL before code calling:
FileSystemRights : FullControl
AccessControlType : Allow
IdentityReference : NT AUTHORITY\SYSTEM
IsInherited : True
InheritanceFlags : None
PropagationFlags : None
FileSystemRights : FullControl
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited : True
InheritanceFlags : None
PropagationFlags : None
FileSystemRights : FullControl
AccessControlType : Allow
IdentityReference : REDACT
IsInherited : True
InheritanceFlags : None
PropagationFlags : None
ACL After Code Calling:
FileSystemRights : FullControl
AccessControlType : Allow
IdentityReference : REDACT
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
FileSystemRights : FullControl
AccessControlType : Allow
IdentityReference : NT AUTHORITY\SYSTEM
IsInherited : True
InheritanceFlags : None
PropagationFlags : None
FileSystemRights : FullControl
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited : True
InheritanceFlags : None
PropagationFlags : None
FileSystemRights : FullControl
AccessControlType : Allow
IdentityReference : REDACT
IsInherited : True
InheritanceFlags : None
PropagationFlags : None
)" This reverts commit 8cabdcf.
Changes to Permissions
fs.chmod
does not set execute permissions on windows https://nodejs.org/api/fs.html#fschmodpath-mode-callback. This means we should also rely on icacls to try to do so.If we still dont have permission, we can collect more information so we know how to fix it better going forward.
This also makes each installer get its own unique folder. SHA is used since it is an algorithm widely available on multiple OS. https://support.globalsign.com/ssl/ssl-certificates-life-cycle/sha-256-compatibility
If this does not work, we can ask for elevation using the vscode library on windows if permission to run the installer is denied.
Command Exeuctor Private Interface Changes
Make Command Executor return an object instead of string. This prevents us from having to run commands twice to get the status and stdout.
Caution must be taken to make sure that the assumptions here in what is returned as stdout vs stderr are correct.