diff --git a/nx/include/switch/kernel/ipc.h b/nx/include/switch/kernel/ipc.h index a5724a6f..87514790 100644 --- a/nx/include/switch/kernel/ipc.h +++ b/nx/include/switch/kernel/ipc.h @@ -449,6 +449,16 @@ static inline Result ipcQueryPointerBufferSize(Handle session, size_t *size) { return rc; } +/** + * @brief Closes the IPC session with proper clean up. + * @param session IPC session handle. + * @return Result code. + */ +static inline Result ipcCloseSession(Handle session) { + u32* buf = (u32*)armGetTls(); + buf[0] = 2; + return ipcDispatch(session); +} ///@} ///@name IPC domain handling diff --git a/nx/include/switch/services/sm.h b/nx/include/switch/services/sm.h index cc592700..2c78ec04 100644 --- a/nx/include/switch/services/sm.h +++ b/nx/include/switch/services/sm.h @@ -134,6 +134,7 @@ static inline void serviceClose(Service* s) { case ServiceType_Normal: case ServiceType_Domain: + ipcCloseSession(s->handle); svcCloseHandle(s->handle); break; diff --git a/nx/source/kernel/tmem.c b/nx/source/kernel/tmem.c index 50c6a637..4e3c38ff 100644 --- a/nx/source/kernel/tmem.c +++ b/nx/source/kernel/tmem.c @@ -92,25 +92,7 @@ Result tmemClose(TransferMemory* t) rc = svcCloseHandle(t->handle); } - if (t->src_addr != NULL) - { - // This fixes a race condition where a remote process that has transfer - // memory mapped, but has not yet had time to unmap it. - // It will still be non-readable in our process until the other process has - // unmapped it, and we cannot free() it without crashing. - while (1) { - MemoryInfo info; - u32 who_cares; - - if (R_FAILED(svcQueryMemory(&info, &who_cares, (u64) t->src_addr))) - fatalSimple(MAKERESULT(Module_Libnx, LibnxError_BadQueryMemory)); - - if (!(info.attr & MemAttr_IsBorrowed)) - break; - - svcSleepThread(1000000); - } - + if (t->src_addr != NULL) { free(t->src_addr); }