If you use the eloquence64 #eloquence addon for the #NVDA#screenreader, 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
@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.
@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.
@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.
@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.
@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.
@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.
@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.
@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.
@nick@draeand It is. When the OpenEVV guys fix all the IBM introduced bugs, I intend to switch over to using there dlls, and just build those into the eloquence64 addon and get rid of IPC. Not doing IPC at all will get us a noticeable 40ms or so.
@fastfinge@nick@draeand I'm surprised that IPC adds double-digit milliseconds. The last time I measured IPC on Windows (specifically for the UI Automation API), inside a VM on a much older machine about 10 years ago, the round trip times were in the range of a few hundred microseconds.
@matt@nick@draeand In the real world, most machines have endpoint security and virus scanning and things that watch IPC carefully, and slow everything down. Especially when you're using TCP. Switching to pipes will probably bring some speedups for some folks, depending.
@matt@nick@draeand If you're curious, here's the biggest speedup I could get with half an hours work. I'm not going to even think about releasing this until I've been using it for a few days, though. It needs testing for clicks/underruns introduced by the much smaller audio buffer. github.com/fastfinge/eloquence_64/tree/perf/onedir-and-smaller-buffer