fix: kernel concurrency, interrupt context, and user VA safety
This commit is contained in:
1 parent
f222bf1f04
commit
b1c55073c7
71 files changed
+2654
-1092
No files matched your search
+18
-29
@@ -14,59 +14,47 @@ namespace montauk::abi {
|
||||
}
|
||||
|
||||
static bool ResolveProcessHandle(Sched::Process* proc, int handle, Ipc::HandleType expectedType,
|
||||
Ipc::Object*& outObject, uint32_t* outRights = nullptr) {
|
||||
Ipc::HandleSnapshot& snapshot) {
|
||||
if (proc == nullptr || handle < 0) return false;
|
||||
|
||||
int slot = Ipc::SlotForPid(proc->pid);
|
||||
if (slot < 0) return false;
|
||||
|
||||
Ipc::HandleType type = Ipc::HandleType::None;
|
||||
Ipc::Object* object = nullptr;
|
||||
uint32_t rights = 0;
|
||||
if (!Ipc::SnapshotHandleForSlot(slot, handle, type, object, rights)) return false;
|
||||
if (type != expectedType || object == nullptr) return false;
|
||||
|
||||
outObject = object;
|
||||
if (outRights != nullptr) *outRights = rights;
|
||||
return true;
|
||||
if (!snapshot.Capture(slot, handle)) return false;
|
||||
return snapshot.type == expectedType && snapshot.object != nullptr;
|
||||
}
|
||||
|
||||
static Ipc::Stream* GetRedirOutStream(Sched::Process* proc) {
|
||||
static Ipc::Stream* GetRedirOutStream(Sched::Process* proc, Ipc::HandleSnapshot& snapshot) {
|
||||
proc = GetRedirTarget(proc);
|
||||
if (proc == nullptr) return nullptr;
|
||||
|
||||
Ipc::Object* object = nullptr;
|
||||
if (!ResolveProcessHandle(proc, proc->ioOutHandle, Ipc::HandleType::Stream, object)) return nullptr;
|
||||
return (Ipc::Stream*)object;
|
||||
if (!ResolveProcessHandle(proc, proc->ioOutHandle, Ipc::HandleType::Stream, snapshot)) return nullptr;
|
||||
return (Ipc::Stream*)snapshot.object;
|
||||
}
|
||||
|
||||
static Ipc::Stream* GetRedirInStream(Sched::Process* proc) {
|
||||
static Ipc::Stream* GetRedirInStream(Sched::Process* proc, Ipc::HandleSnapshot& snapshot) {
|
||||
proc = GetRedirTarget(proc);
|
||||
if (proc == nullptr) return nullptr;
|
||||
|
||||
Ipc::Object* object = nullptr;
|
||||
if (!ResolveProcessHandle(proc, proc->ioInHandle, Ipc::HandleType::Stream, object)) return nullptr;
|
||||
return (Ipc::Stream*)object;
|
||||
if (!ResolveProcessHandle(proc, proc->ioInHandle, Ipc::HandleType::Stream, snapshot)) return nullptr;
|
||||
return (Ipc::Stream*)snapshot.object;
|
||||
}
|
||||
|
||||
static Ipc::Mailbox* GetRedirKeyMailbox(Sched::Process* proc) {
|
||||
static Ipc::Mailbox* GetRedirKeyMailbox(Sched::Process* proc, Ipc::HandleSnapshot& snapshot) {
|
||||
proc = GetRedirTarget(proc);
|
||||
if (proc == nullptr) return nullptr;
|
||||
|
||||
Ipc::Object* object = nullptr;
|
||||
if (!ResolveProcessHandle(proc, proc->ioKeyHandle, Ipc::HandleType::Mailbox, object)) return nullptr;
|
||||
return (Ipc::Mailbox*)object;
|
||||
if (!ResolveProcessHandle(proc, proc->ioKeyHandle, Ipc::HandleType::Mailbox, snapshot)) return nullptr;
|
||||
return (Ipc::Mailbox*)snapshot.object;
|
||||
}
|
||||
|
||||
static int DuplicateHandleBetweenSlots(int srcSlot, int handle, int dstSlot) {
|
||||
if (srcSlot < 0 || dstSlot < 0 || handle < 0) return -1;
|
||||
|
||||
Ipc::HandleType type = Ipc::HandleType::None;
|
||||
Ipc::Object* object = nullptr;
|
||||
uint32_t rights = 0;
|
||||
if (!Ipc::SnapshotHandleForSlot(srcSlot, handle, type, object, rights)) return -1;
|
||||
if ((rights & Ipc::RightDup) == 0) return -1;
|
||||
return Ipc::InstallHandleForSlot(dstSlot, object, type, rights);
|
||||
Ipc::HandleSnapshot snapshot;
|
||||
if (!snapshot.Capture(srcSlot, handle)) return -1;
|
||||
if ((snapshot.rights & Ipc::RightDup) == 0) return -1;
|
||||
return Ipc::InstallHandleForSlot(dstSlot, snapshot.object, snapshot.type, snapshot.rights);
|
||||
}
|
||||
|
||||
static bool ConfigureRedirWaitsetForSlot(int slot, Sched::Process* proc) {
|
||||
@@ -100,12 +88,13 @@ namespace montauk::abi {
|
||||
|
||||
int total = 0;
|
||||
while (total < len) {
|
||||
uint64_t observedWake = Sched::ObserveObjectWake(stream);
|
||||
int written = Ipc::StreamWrite(stream, data + total, len - total, false);
|
||||
if (written < 0) {
|
||||
return (total > 0) ? total : -1;
|
||||
}
|
||||
if (written == 0) {
|
||||
Sched::BlockOnObject(stream, 0);
|
||||
Sched::BlockOnObjectSince(stream, 0, observedWake);
|
||||
continue;
|
||||
}
|
||||
total += written;
|
||||
|
||||
Reference in new issue
Block a user