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

Fixes uninstaller breaking CMD.exe by corrupting registry keys #521

Merged
merged 3 commits into from
Sep 5, 2022

Conversation

guimondmm
Copy link
Contributor

@guimondmm guimondmm commented Jun 22, 2022

Fixes ContinuumIO/anaconda-issues#12938 and addresses ContinuumIO/anaconda-issues#12735.

On 23 Oct 2020, conda/conda@b4f3210 changed the regex pattern used by the init_cmd_exe_registry function in conda/core/initialize.py to configure the conda hook for CMD.exe on Windows:

@@ -1430 +1435 @@ def init_cmd_exe_registry(target_path, conda_prefix, reverse=False):
-            r'(\"[^\"]*?conda[-_]hook\.bat\")',
+            r'(if exist \"[^\"]*?conda[-_]hook\.bat\" \"[^\"]*?conda[-_]hook\.bat\")',

This changed the format of the string written by the conda init command to either of the following Windows Registry variables:

  • HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
  • HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun

However, the regex pattern used by the rm_regkeys function in constructor/nsis/_nsis.py was not updated accordingly.

Because of that oversight, when a Windows user who has run conda init after conda/conda@b4f3210 attempts to uninstall Anaconda using Uninstall-Anaconda3.exe, the conda hook isn't deleted properly from the registry by the constructor/nsis/_nsis.py script, which breaks CMD.exe and causes system instability.

This is because the old regex pattern ((\s+&\s+)?\"[^\"]*?conda[-_]hook\.bat\") deleted by constructor/nsis/_nsis.py matches twice in the new pattern (if exist \"[^\"]*?conda[-_]hook\.bat\" \"[^\"]*?conda[-_]hook\.bat\") set by conda/core/initialize.py, and leaves behind if exist with trailing spaces.

When CMD.exe is launched without the /D flag, it attempts to read the AutoRun variable from the registry, and if it is set, it tries to execute the specified string first. The syntax of the if exist command is invalid, so CMD.exe silently terminates with exit code 1. This breaks the Command Prompt as well as batch files, and causes several apps to crash or misbehave. Windows repair tools like SFC.exe and DISM.exe don't detect the corrupted registry variables, and reinstalling Anaconda doesn't fix the issue. Unless the user knows about obscure CMD.exe flags and registry keys, their system is effectively hosed.

To address the issue, I've updated the regex pattern in the rm_regkeys function of constructor/nsis/_nsis.py to match both the older pattern and the newer one from the init_cmd_exe_registry function in conda/core/initialize.py.

@conda-bot
Copy link
Contributor

We require contributors to sign our Contributor License Agreement and we don't have one on file for @guimondmm.

In order for us to review and merge your code, please e-sign the Contributor License Agreement PDF. We then need to manually verify your signature. We will ping the bot to refresh the PR status when we have confirmed your signature.

@guimondmm
Copy link
Contributor Author

Signed the CLA.

@jaimergp
Copy link
Contributor

@conda-bot check

@conda-bot conda-bot added the cla-signed [bot] added once the contributor has signed the CLA label Aug 15, 2022
jaimergp
jaimergp previously approved these changes Aug 15, 2022
Copy link
Contributor

@jaimergp jaimergp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed investigation and submitted patch @guimondmm!

I think it makes sense. Unfortunately we don't have tests for uninstallers yet, so I'll have to check manually... which involves creating a custom conda-standalone.exe 😬

I'll see if I find the time to do it properly, but for now I trust you and will leave the merge to other members of @conda/constructor if they are more confident!

constructor/nsis/_nsis.py Outdated Show resolved Hide resolved
Co-authored-by: guimondmm <guimondmm@gmail.com>
@jaimergp jaimergp merged commit de1ce16 into conda:main Sep 5, 2022
@jaimergp
Copy link
Contributor

jaimergp commented Sep 5, 2022

Thank you so much @guimondmm!

@YouJiacheng
Copy link

YouJiacheng commented Sep 14, 2022

Thank you so much!
But, why not use the same method as conda init --reverse? That might be more robust to upstream pattern change.
Moreover, it seems that current method will break AutoRun with value like <Conda AutoRun> & <Other App AutoRun>, by substituting it to & <Other App AutoRun>. But it is invalid to have beginning & in CMD.exe

@jaimergp
Copy link
Contributor

That's an excellent point. We can investigate how that works in a separate PR. The reason would be that constructor wasn't using a full conda until version 3, so the uninstall code probably predates the possibility of using conda init --reverse.

@AngusMaiden
Copy link

This is still an issue with the installers available from https://docs.conda.io/en/latest/miniconda.html
I'm not sure if it's relevant but when I look at the merge commit's associated workflow, the "Upload" action was skipped.

This is a critical issue as is pointed out in the fix, because it can leave the OS severely broken, and should make sure it's not only merged but also uploaded to the installers.

@jaimergp
Copy link
Contributor

jaimergp commented Dec 5, 2022

The installers you can currently find in that website are built by a separate constructor fork. Pinging @pseudoyim for visibility / awareness.

@DHowett
Copy link

DHowett commented Jul 5, 2023

The syntax of the if exist command is invalid, so CMD.exe silently terminates with exit code 1. This breaks the Command Prompt as well as batch files, and causes several apps to crash or misbehave.

We just started seeing an uptick in reports of this (hi! I'm the engineering manager for the Windows Console and Terminal (and regrettably, CMD)). Regardless of the root cause, we've added an early-out to Autorun processing :)

Hopefully this fix plus yours will help remediate a lot of the trouble here. 😄

image

@AngusMaiden
Copy link

AngusMaiden commented Jul 5, 2023

The installers you can currently find in that website are built by a separate constructor fork. Pinging @pseudoyim for visibility / awareness.

@jaimergp @pseudoyim was this ever fixed such that the old windows installers for Python 3.8 and Python 3.9 on the miniconda install page (https://docs.conda.io/en/latest/miniconda.html) were updated with the fixed version?

@jaimergp
Copy link
Contributor

Depends on what you mean by "old". The most recent ones should contain this fix. I think from January 2023 on, but someone else confirm. cc @dbast @marcoesters

@AngusMaiden
Copy link

Depends on what you mean by "old". The most recent ones should contain this fix. I think from January 2023 on, but someone else confirm. cc @dbast @marcoesters

By "old" I just meant the installers for Miniconda for Python 3.8 and 3.9. Because I'm wondering if this fix was applied only to the latest version (for Python 3.10), or were these versions' installers rebuilt and re-uploaded for those older versions as well?

I can and should test myself, however, but I just thought you guys might know the answer already.

@jaimergp
Copy link
Contributor

Yea I think they are all built at the same time. You can check the Properties tab of the installer file too: https://conda.github.io/constructor/howto/#find-out-the-used-constructor-version

@github-actions github-actions bot added the locked [bot] locked due to inactivity label Jul 10, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 10, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla-signed [bot] added once the contributor has signed the CLA locked [bot] locked due to inactivity
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Registry key left behind after uninstall, breaks CMD
6 participants