Skip to content
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

Merged
merged 20 commits into from
Jul 3, 2024

Conversation

nagilson
Copy link
Member

@nagilson nagilson commented Jun 25, 2024

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.

nagilson and others added 8 commits June 25, 2024 16:11
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
@nagilson nagilson changed the title Elevate if EPERM error hit when trying to open installer.exe Prevent EPERM error hit when trying to open installer.exe Jul 2, 2024
@nagilson nagilson requested review from a team and MiYanni July 2, 2024 23:58
Comment on lines -52 to -55
export function InstallToStrings(key: DotnetInstall | null) {
if (!key) {
return { installKey: '', version: '', architecture: '', isGlobal: '', installMode: '' };
}
Copy link
Member

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.

Copy link
Member Author

@nagilson nagilson Jul 3, 2024

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.

Copy link
Member

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);
Copy link
Member

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?

Copy link
Member Author

@nagilson nagilson Jul 3, 2024

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);
Copy link
Member

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).

Copy link
Member Author

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

@nagilson nagilson merged commit 8cabdcf into dotnet:main Jul 3, 2024
9 checks passed
nagilson added a commit that referenced this pull request Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants