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
other apps may crash or cause errors when an NVDA installation is updated #7563
Labels
Milestone
Comments
michaelDCurran
added
bug/app-crash
p2
https://github.com/nvaccess/nvda/blob/master/projectDocs/issues/triage.md#priority
labels
Sep 4, 2017
Blimey..
Anyway, this might explain why sometimes programs vanish or nvda appears to
hang but explorer has gone away. I wonder if something similar but delayed
is what is crashing various versions of Outlook as I've noted on the user
list?
They do not say they specifically did an update but presumably this can
also happen on a reboot or of a switch to and from a portable to an
installed version as well?
I don't quite get how you can have a different folder for dlls every time
though.
Brian
bglists@blueyonder.co.uk
Sent via blueyonder.
Please address personal email to:-
briang1@blueyonder.co.uk, putting 'Brian Gaff'
in the display name field.
|
It is just a different folder per version. I.e. c:\program files
(x86)\nvda\lib\2017.4 or c:\program files
(x86)\nvda\lib\snapshot-next-14234-a1b2c3d4e5.
Not a different folder per run.
We are just trying to avoid two differently compiled copies from using
the same path for a dll.
|
hi. why it is not possible to free library just before exiting nvda? |
Simply not possible, when you're talking about injection into other
processes etc.
|
Does this mean then that if one runs from snaps you eventually end up either
huge numbers of duplicate folders each with the name of the update , but
containing the same files.
I remember seeing some routine called unlock which was supposed to stop
this kind of thing happening as it could stop deletion of files until a
system restart otherwise.
Brian
bglists@blueyonder.co.uk
Sent via blueyonder.
Please address personal email to:-
briang1@blueyonder.co.uk, putting 'Brian Gaff'
in the display name field.
|
Only if you run a huge number of snapshots without rebooting. All old
dlls will be deleted on reboot.
|
That is what I thought, so it looks first on a reboot and removes the unused
ones.
I tend to do this running of many snaps when trying to get back to the
working one if its broken. I tend to use master for working and installed
and next as a portable but obviously in different folders, keeping a working
portable copy of the release version in a folder which I can use if trouble
comes along.
So on portable versions then, would the extra folders get deleted when you
shut the installed version and run a specific portable one?
Brian
bglists@blueyonder.co.uk
Sent via blueyonder.
Please address personal email to:-
briang1@blueyonder.co.uk, putting 'Brian Gaff'
in the display name field.
|
Hi. There's an I in 'compared' that shouldn't be there. :) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
Steps to reproduce:
Expected behavior:
The apps should not crash.
Actual behavior:
One or more of the apps crash.
System configuration:
Windows version: 10.0.16278 64-bit
Technical info:
We forget to unhookWinEvent in NVDAHelperRemote
NVDAHelperRemote injects into applications with foreground and focus winEvents. In inprocMgrThreadFunc, it then registers another winEvent limited to that process (inproc_winEventCallback) that listens for all possible winEvents. On termination, the injection winEvent is unregistered, but the process-specific winEvent is not. This leaves NVDAHelperRemote.dll in the process for ever. It will also respond to winEvents even though nvdaHelperRemote is terminated which may cause instability or a crash. It is necessary that inproc_winEventCallback be unregistered before inprocMgrThreadFunc exits.
Accidentally execute invalid memory
It is possible to accidentally cause Windows to execute incorrect memory in an in-context winEvent hook and thereby crash the injected process, when using a valid dll and a valid executable function pointer from that dll.
Specifically:
Create 2 dlls. Each with a winEventCallback function. However, add extra code to dll1's dllMain so that it does an extra addref (GetModuleHandleEx) on process attach so that it never unloads.
Then:
A. Rename dll1 to tempPath
A. Load dll 1 via tempPath into process1
B. Call SetWinEventHook giving it the handle of dll1, and the function pointer of a WINEVENTCALLBACK within dll1, make it listen for events in process2, in-context.
C. Fire a winEvent in process2, so that Windows injects dll1 and executes the winEventCallback.
D. Unhook dll1's winEventCallback in process1
E. Rename dll2 to tempPath (replacing dll1)
F. Load dll2 via tempPath into process1
G. Call SetWinEventHook giving it the handle of dll2, and the function pointer of a WINEVENTCALLBACK within dll2, make it listen for events in process2, in-context.
H. Fire a winEvent in process2, so that Windows should inject dll2 and execute the winEventCallback.
However:
As dll1 and dll2 both have exactly the same path, and dll1 is still loaded, Windows does not bother loading dll2. Rather it uses dll1's memory address to calculate the physical location of the winEventCalback. But, as this was originally from dll2, it hits random memory!
In other words, It seems that the only information sent from process1 to process2 is the path of the dll, and the offset of the winEventCallback (I.e. winEventCallback minus dll base address). Then in process2, it does a simple LoadLibrary(path) and calculates dllHandle plus winEventCallback offset.
Practical outcome
Normally when updating an NVDA installation, as nvdaHelperRemote.dll did not change its layout, things go okay. However, if nvdaHelperRemote is changed in any dramatic way (such as a segment being removed or code moved around such as with the mentioned Next snapshot) then if the old nvdaHelperRemote takes a long time to unload from an app, and in deed it is still there when the new NVDA tries to inject, Windows will refuse to load in the new copy as it thinks it already has it, and then executes from the wrong memory location.
We specifically hit this problem when implementing pr #7535
Suggested fix
We should place all NVDA dlls in a version-specific directory, so that the path to any NVDA dll changes for each version.
The text was updated successfully, but these errors were encountered: