On Thu Jan 30 16:42:22 2025 +0000, Elizabeth Figura wrote:
Like other internal objects they go through server_wait_for_object().
I mean that the `NtWaitForMultipleObjects()` call will always return `STATUS_OBJECT_TYPE_MISMATCH` with a completion port object under ntsync because of the `no_get_inproc_sync` handler being used (the path goes like: `object->ops->get_fast_sync()` -> `get_linux_sync_obj()` -> (ntdll.so) `get_fast_sync_obj()` -> `fast_wait()`)
The failure of `NtWaitForMultipleObjects()` gets passed to `NtRemoveIoCompletion()` (which is the function Paul mentioned above) which causes that function to return early and not call the `get_thread_completion()` server function that fills up the `value` (later `*overlapped`) parameter with data
`GetQueuedCompletionStatus()` call now returns from that completion function with a failure and a very likely NULL `*overlapped` value (that `*overlapped` value gets passed to `CONTAINING_RECORD()` macro inside quartz's `io_thread()` function inside filesource.c which causes an integer underflow that gets accidentally picked up by the `assert()` nearby which prevents the error path from even being called)
So one way of preventing this issue could be to just return `STATUS_NOT_SUPPORTED` for the `get_fast_sync()` handler in `completion_wait_ops` (the other way could be what I've suggested above)
The relevant `quartz` function could maybe also set a sane value for `req` (so that the error path gets actually taken)