16h
If you use the eloquence64 addon for the , a critical security release is now available. This is a critical update! Please update as soon as possible.

If you use Eloquence64 on secure screens, after the update, you must
IMMEDIATELY! go to NVDA's settings dialogue, select eloquence from the list box, and press the "copy helper to system config" button again.

It fixes the following issues:
* fix: eloquence64 now clears its log file on start
* Fix: in some cases, eloquence64 could write to its log file at 30 megs per second
* fix: in some cases, eloquence64 created multiple temp files and directories that could not be removed
* fix: in some cases, eloquence64 could unexpectedly leave a port open on the computer
* fix: the port and key to communicate with eloquence could be intercepted by other processes running on the machine
* fix: in rare cases, it could have been possible for other processes on the user's machine to cause the addon to load and run arbitrary Python code by causing it to deserialize an attacker supplied pickle. If the addon was running on a secure screen, this would mean instant privilege escalation.
* fixed: crashing or frozen NVDA will no longer leave orphaned eloquence processes behind
* fix: more reliable pause and break lengths
* security hardening: switch to named pipes with DACL for IPC, ensuring no other process can use the 32-bit host

Release page:
github.com/fastfinge/eloquence_64/releases/tag/v21

Direct download:
github.com/fastfinge/eloquence_64/releases/download/v21/Eloquence-v21.nvda-addon

1
15
3
0
User avatar
Ethin Probst @draeand@the-gdn.net
10h
@fastfinge Hate to say it but these security issues with pickle are exactly why you shouldn't use pickle.
1
0
0
0
5h
@draeand In my case, I need something fast and built in. It really is the best fit. The issue here was using tcp for ipc. That was a poor decision that just happened rather than being intentionally considered.
1
0
0
0
User avatar
Ethin Probst @draeand@the-gdn.net
3h
@fastfinge I mean, you could use flat buffers or similar. That’s not built-in perhaps but it also doesn’t come with the risk of arbitrary RCE vulnerabilities in your code if you choose to use IPC mechanisms like this or to allow third parties to interact with serialized data. The downside is it’s an external dependency, but it’s insanely fast. Pickle is something you should only use if you have absolute control over the data that you unpickle.
1
0
0
0
2h
@draeand Yes, and that was the problem. Third parties should not have been able to interact with the process that unpickles data. They could because I allowed things to happen as the code took shape over the past six years, and failed to review third partie PR's closely enough, rather than creating an intentional design for it. It then bit me when I forgot to correctly clean up the process that was listening to the TCP socket as part of other changes. The correct answer in this case was to move to named pipes, with process and group ased ACL, not dump pickle.
1
0
0
0
1h
@draeand The ultimate solution is to rewrite the 32-bit eloquence host in something like rust, the way eloquence64RS does. But I don't speak or understand rust, so I'm not confident either writing it myself, or reviewing and sanity checking an AI generated rust host. Plus, NVDA itself, and the addon portion, are in Python. And I prefer to only require contributors (and me) to deal with a single programming language. Based on that round of bug-fixing, I'm already completely incapable of doing an adequate job. More complexity will not help me.
1
0
0
0
User avatar
Nick Giannak III @nick@hkc.social
1h
@fastfinge @draeand I get why you made the decisions you did, I really do. But I genuinely wonder whether rewriting the host in C# wouldn't be the right call for you. Yes, the contributors issue, but I'd ask the most regular ones if they'd be happy with such a move - you genuinely get a performance uplift doing it, for instance.
1
0
0
0
1h
@nick @draeand I wouldn't, though. First the dotnet runtime would now be required, and would be a huge memory suck. Second the only lag Python brings is the first startup/JIT compile. Once that happens, it's just reading data off a pipe and passing it to eloquence. Getting rid of TCP saved me somewhere between 40 and 60 nanoseconds. But that's well below the limit of human perceivability. And generating NVDA indexes etc still happens in Python, because that's what NVDA uses. So a low level language just can't save anything here. The reason your rust driver feels more accurate is because you're playing back chunks sooner, and thus making indexing slightly less accurate in return. That's not a tradeoff I'd want to make. If I did, it could just as easily be made in Python.
3
0
0
0
User avatar
Nick Giannak III @nick@hkc.social
1h
@fastfinge @draeand Ah, I forgot about the .net runtime, so you'd get literally no RAM savings. Rust does get you those RAM savings, but I'll stand correct and admit that may be all it's giving me. Obviously, the main difference between our addons is that I'm willing to make that tradeoff in the name of responsiveness where you aren't, and that might be a big enough difference in daily use for both addons to need to exist.
1
0
0
0
1h
@nick @draeand Yup, I regularly use stuff like unspoken and earcons, so having the sounds line up where they should is really really important to me.
1
0
0
0
User avatar
Nick Giannak III @nick@hkc.social
1h
@fastfinge @draeand As it happens, I do have one question. Have you tried the OpenEVV addon with Unspoken? Is it still early? Because that thing is just as quick as 64RS.
2
0
0
0
1h
@nick @draeand Just did some quick benchmarking. Based on the hotpath, a rewrite away from python could save as much as, get ready, 0.0005% of processing time.
1
0
0
0

User avatar
Nick Giannak III @nick@hkc.social
1h
@fastfinge @draeand LOL. ...Which honestly just means my experiment wasn't worth doing, except only insofar as it makes my experience using Windows on a Macbook Neo better as that's a very constrained environment. Honestly, when OpenEVV is actually ready, I'm getting out.
2
0
0
0
@nick One of these days I really do need to backport your dictionary handling code. But...that's HAAAARD WORK! wines I don't wanna! The dictionary code as it currently exists makes me sad and afraid.
0
0
0
0
User avatar
Ethin Probst @draeand@the-gdn.net
16m
@nick @fastfinge I honestly wonder if a C++ rewrite would be better. If the host only acts as a proxy to the ECI dll, then it should, in theory, be very simple to rewrite, although if you want serialization you'd need more deps (but most could be single-header).
1
0
0
0
@draeand @nick If we want to rewrite the world, the actually correct way to do this is write ECI64.dll, that's just a shim to call the 32-bit DLL, and then have anything at all that's a 64-bit process and wants to use eloquence load ECI64.dll. The primary reason I haven't done that is lack of talent. Though in hindsight, it probably would have actually been simpler than what I did wind up doing.
1
0
0
0
User avatar
Ethin Probst @draeand@the-gdn.net
12m
@fastfinge @nick You can't load a 32-bit DLL into a 64-bit address space though, which is the fundamental issue. I mean okay, I'll be a pedant and say that theoretically you could in fact load a 32-bit DLL into a 64-bit process, but it would be very very painful and require a bunch of low level hacks and black magic (and I'm pretty sure you would need to in effect be the library loader at that point). Not worth it unless you have a really really good reason or you like over-engineering things.
1
0
0
0
@draeand @nick No, but you could have ECI64.dll handle all of the IPC stuff, using what ever method you want, behind the scenes in a way that's largely invisible to the 64-bit app. And then every single app that wants to use eloquence doesn't have to do its own IPC.
1
0
0
0
User avatar
Ethin Probst @draeand@the-gdn.net
9m
@fastfinge @nick Very true, that's probably the best route unless you really want to learn how an operating system works. Which I would encourage, if only to learn new things!
1
0
0
0
@draeand @nick Hah. I'm a guy who forgot to clean up a process on close and left it that way for, like, months. I'm far away from doing low level OS work.
2
0
0
0
User avatar
Ethin Probst @draeand@the-gdn.net
7m
@fastfinge @nick I mean... I didn't sanitize XML with Prism's SAPI backend for quite a long time, so... I don't think you have anything to worry about.
0
0
1
0
User avatar
Ethin Probst @draeand@the-gdn.net
5m
@fastfinge @nick Damnit, now the nerd side of me is working through actually making that work -- loading a 32-bit DLL into a 64-bit address space... Oooof
2
0
0
0
@draeand @nick If it wasn't for OpenEVV existing, and making all of this not matter within a year, I would probably write ECI64 in C and have it handle IPC with ECI32 via pipes or something. Then the three different eloquence addons can stop doing IPC, each in a slightly different way, and we can all focus on the actual differences and tradeoffs each one makes. Although, I don't think I can have a shared memory buffer between a 32 bit and a 64 bit process, can I? I still need pipes or something.
1
0
0
0
User avatar
Ethin Probst @draeand@the-gdn.net
41s
@fastfinge @nick Yep I'm 99 percent sure you can. Although I'd neeed to empirically verify that and I just woke up so am too lazy to write 50 LoC to test it. 😂 As for OpenEVV, I think it's a good project although I think the language choice was very bad, in the sense that the code is entirely unreadable and your taking the advice of an LLM (and I don't like that level of autonomy being removed from me but that may just be me...)
0
0
0
0
@draeand @nick And there is a thing you can license that will do exactly that: load 32-bit libraries into 64-bit apps. But the guy wants like $3000 to license it. His target market is businesses with old codebases they can't modernize. And he doesn't offer a demo.
0
0
0
0