On Thursday, 25 January 2024 12:55:04 CST Andy Lutomirski wrote: > On Wed, Jan 24, 2024 at 7:42 PM Elizabeth Figura > <zfigura@xxxxxxxxxxxxxxx> wrote: > > > > On Wednesday, 24 January 2024 16:56:23 CST Elizabeth Figura wrote: > > > On Wednesday, 24 January 2024 15:26:15 CST Andy Lutomirski wrote: > > > > > > > On Tue, Jan 23, 2024 at 4:59 PM Elizabeth Figura > > > > <zfigura@xxxxxxxxxxxxxxx> wrote: > > > > > > > > > > > > > > > > > > > ntsync uses a misc device as the simplest and least intrusive uAPI > > > > > interface. > > > > > > > > > > > > > > > > > > > Each file description on the device represents an isolated NT instance, > > > > > intended to correspond to a single NT virtual machine. > > > > > > > > > > > > If I understand this text right, and if I understood the code right, > > > > you're saying that each open instance of the device represents an > > > > entire universe of NT synchronization objects, and no security or > > > > isolation is possible between those objects. For single-process use, > > > > this seems fine. But fork() will be a bit odd (although NT doesn't > > > > really believe in fork, so maybe this is fine). > > > > > > > > Except that NT has *named* semaphores and such. And I'm pretty sure > > > > I've written GUI programs that use named synchronization objects (IIRC > > > > they were events, and this was a *very* common pattern, regularly > > > > discussed in MSDN, usenet, etc) to detect whether another instance of > > > > the program is running. And this all works on real Windows because > > > > sessions have sufficiently separated namespaces, and the security all > > > > works out about as any other security on Windows, etc. But > > > > implementing *that* on top of this > > > > file-description-plus-integer-equals-object will be fundamentally > > > > quite subject to one buggy program completely clobbering someone > > > > else's state. > > > > > > > > Would it make sense and scale appropriately for an NT synchronization > > > > *object* to be a Linux open file description? Then SCM_RIGHTS could > > > > pass them around, an RPC server could manage *named* objects, and > > > > they'd generally work just like other "Object Manager" objects like, > > > > say, files. > > > > > > > > > It's a sensible concern. I think when I discussed this with Alexandre > > > Julliard (the Wine maintainer, CC'd) the conclusion was this wasn't > > > something we were concerned about. > > > > > > While the current model *does* allow for processes to arbitrarily mess > > > with each other, accidentally or not, I think we're not concerned with > > > the scope of that than we are about implementing a whole scheduler in > > > user space. > > > > > > For one, you can't corrupt the wineserver state this way—wineserver > > > being sort of like a dedicated process that handles many of the things > > > that a kernel would, and so sometimes needs to set or reset events, or > > > perform NTSYNC_IOC_KILL_MUTEX, but never relies on ntsync object state. > > > Whereas trying to implement a scheduler in user space would involve the > > > wineserver taking locks, and hence other processes could deadlock. > > > > > > For two, it's probably a lot harder to mess with that internal state > > > accidentally. > > > > > > [There is also a potential problem where some broken applications > > > create a million (literally) sync objects. Making these into files runs > > > into NOFILE. We did specifically push distributions and systemd to > > > increase those limits because an older solution *did* use eventfds and > > > *did* run into those limits. Since that push was successful I don't > > > know if this is *actually* a concern anymore, but avoiding files is > > > probably not a bad thing either.] > > > > Of course, looking at it from a kernel maintainer's perspective, it wouldn't > > be insane to do this anyway. If we at some point do start to care about cross- > > process isolation in this way, or if another NT emulator wants to use this > > interface and does care about cross-process isolation, it'll be necessary. At > > least it'd make sense to make them separate files even if we don't implement > > granular permission handling just yet. > > I'm not convinced that any complexity at all beyond using individual > files is needed for granular permission handling. Unless something > actually needs permission bits on different files pointing at the same > sync object (which I believe NT supports, but it's sort of an odd > concept and I'm not immediately convinced that anything uses it), > merely having individual files ought to do the trick. Handling of who > has permission to open a given named object can live in a daemon, and > I'd guess that Wine even already implements this. This is mostly correct. NT has file descriptors and descriptions (the former is called a "handle"), though unlike Unix access bits are specific to the *descriptor* (handle). I don't know if anything uses it, but we do currently implement that basic functionality, so I can't say that nothing does either. So inasmuch as access to someone else's object is a concern, access to your object with bits you don't have permission for could be a concern along the same lines. However, from conversation with Alexandre I believe it'd be fine to just implement those checks in user space. > And keeping everything together gives me flashbacks of Windows 95 and > Mac OS pre-X. Sure, in principle the software wasn't malicious, but > there was no shortage whatsoever of buggy crap out there, and systems > were quite unstable. Even just: > > CreateSemaphore(); > fork(); > sleep a few seconds; > exit(); > > seems like it could corrupt the shared namespace world. (Obviously no > one would ever do that, right?) > > Also, handle leaks: > > while(true) { > make a subprocess, which creates a semaphore and crashes; > } For whatever it's worth, this particular thing wouldn't be a concern; Wine's "kernel" daemon already has to detect when a process dies and close all its outstanding handles.