Make sure all data is initialized in srv and errf

Prior to system version 11.0, the kernel filled the resulting handle with junk in case of failure, when calling svcConnectToPort, etc.

In some situations libctru could accidentally close valid handles.
This commit is contained in:
TuxSH 2022-04-11 21:15:08 +01:00
parent ebb5305188
commit cf538b1fa8
2 changed files with 47 additions and 34 deletions

View File

@ -18,10 +18,12 @@ Result errfInit(void)
if (AtomicPostIncrement(&errfRefCount)) return 0; if (AtomicPostIncrement(&errfRefCount)) return 0;
rc = svcConnectToPort(&errfHandle, "err:f"); rc = svcConnectToPort(&errfHandle, "err:f");
if (R_FAILED(rc)) goto end; if (R_FAILED(rc))
{
errfHandle = 0;
errfExit();
}
end:
if (R_FAILED(rc)) errfExit();
return rc; return rc;
} }
@ -29,7 +31,8 @@ void errfExit(void)
{ {
if (AtomicDecrement(&errfRefCount)) if (AtomicDecrement(&errfRefCount))
return; return;
svcCloseHandle(errfHandle); if (errfHandle != 0) svcCloseHandle(errfHandle);
errfHandle = 0;
} }
Handle* errfGetSessionHandle(void) Handle* errfGetSessionHandle(void)

View File

@ -35,10 +35,13 @@ Result srvInit(void)
rc = svcDuplicateHandle(&srvHandle, *srvPmGetSessionHandle()); // Prior to system version 7.0 srv:pm was a superset of srv: rc = svcDuplicateHandle(&srvHandle, *srvPmGetSessionHandle()); // Prior to system version 7.0 srv:pm was a superset of srv:
else else
rc = svcConnectToPort(&srvHandle, "srv:"); rc = svcConnectToPort(&srvHandle, "srv:");
if (R_FAILED(rc)) goto end;
rc = srvRegisterClient(); if (R_SUCCEEDED(rc))
end: rc = srvRegisterClient();
else
// Prior to system version 11.0, the kernel filled the resulting handle with junk in case of failure
srvHandle = 0;
if (R_FAILED(rc)) srvExit(); if (R_FAILED(rc)) srvExit();
return rc; return rc;
} }
@ -96,11 +99,11 @@ Result srvEnableNotification(Handle* semaphoreOut)
cmdbuf[0] = IPC_MakeHeader(0x2,0,0); cmdbuf[0] = IPC_MakeHeader(0x2,0,0);
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc; rc = svcSendSyncRequest(srvHandle);
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
if(semaphoreOut) *semaphoreOut = R_SUCCEEDED(rc) ? cmdbuf[3] : 0;
if(semaphoreOut) *semaphoreOut = cmdbuf[3]; return rc;
return cmdbuf[1];
} }
Result srvRegisterService(Handle* out, const char* name, int maxSessions) Result srvRegisterService(Handle* out, const char* name, int maxSessions)
@ -113,11 +116,11 @@ Result srvRegisterService(Handle* out, const char* name, int maxSessions)
cmdbuf[3] = strnlen(name, 8); cmdbuf[3] = strnlen(name, 8);
cmdbuf[4] = maxSessions; cmdbuf[4] = maxSessions;
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc; rc = svcSendSyncRequest(srvHandle);
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
if(out) *out = R_SUCCEEDED(rc) ? cmdbuf[3] : 0;
if(out) *out = cmdbuf[3]; return rc;
return cmdbuf[1];
} }
Result srvUnregisterService(const char* name) Result srvUnregisterService(const char* name)
@ -144,11 +147,11 @@ Result srvGetServiceHandleDirect(Handle* out, const char* name)
cmdbuf[3] = strnlen(name, 8); cmdbuf[3] = strnlen(name, 8);
cmdbuf[4] = (u32)srvGetBlockingPolicy(); // per-thread setting, default is blocking cmdbuf[4] = (u32)srvGetBlockingPolicy(); // per-thread setting, default is blocking
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc; rc = svcSendSyncRequest(srvHandle);
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
if(out) *out = R_SUCCEEDED(rc) ? cmdbuf[3] : 0;
if(out) *out = cmdbuf[3]; return rc;
return cmdbuf[1];
} }
Result srvRegisterPort(const char* name, Handle clientHandle) Result srvRegisterPort(const char* name, Handle clientHandle)
@ -191,11 +194,11 @@ Result srvGetPort(Handle* out, const char* name)
cmdbuf[3] = strnlen(name, 8); cmdbuf[3] = strnlen(name, 8);
cmdbuf[4] = 0x0; cmdbuf[4] = 0x0;
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc; rc = svcSendSyncRequest(srvHandle);
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
if(out) *out = R_SUCCEEDED(rc) ? cmdbuf[3] : 0;
if(out) *out = cmdbuf[3]; return rc;
return cmdbuf[1];
} }
Result srvWaitForPortRegistered(const char* name) Result srvWaitForPortRegistered(const char* name)
@ -245,11 +248,11 @@ Result srvReceiveNotification(u32* notificationIdOut)
cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000 cmdbuf[0] = IPC_MakeHeader(0xB,0,0); // 0xB0000
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc; rc = svcSendSyncRequest(srvHandle);
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
if(notificationIdOut) *notificationIdOut = R_SUCCEEDED(rc) ? cmdbuf[2] : 0;
if(notificationIdOut) *notificationIdOut = cmdbuf[2]; return rc;
return cmdbuf[1];
} }
Result srvPublishToSubscriber(u32 notificationId, u32 flags) Result srvPublishToSubscriber(u32 notificationId, u32 flags)
@ -274,12 +277,18 @@ Result srvPublishAndGetSubscriber(u32* processIdCountOut, u32* processIdsOut, u3
cmdbuf[0] = IPC_MakeHeader(0xD,1,0); // 0xD0040 cmdbuf[0] = IPC_MakeHeader(0xD,1,0); // 0xD0040
cmdbuf[1] = notificationId; cmdbuf[1] = notificationId;
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc; rc = svcSendSyncRequest(srvHandle);
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
if(processIdCountOut) *processIdCountOut = cmdbuf[2]; if (R_SUCCEEDED(rc))
if(processIdsOut) memcpy(processIdsOut, &cmdbuf[3], cmdbuf[2] * sizeof(u32)); {
if(processIdCountOut) *processIdCountOut = cmdbuf[2];
if(processIdsOut) memcpy(processIdsOut, &cmdbuf[3], cmdbuf[2] * sizeof(u32));
}
else if(processIdCountOut)
*processIdCountOut = 0;
return cmdbuf[1]; return rc;
} }
Result srvIsServiceRegistered(bool* registeredOut, const char* name) Result srvIsServiceRegistered(bool* registeredOut, const char* name)
@ -291,11 +300,12 @@ Result srvIsServiceRegistered(bool* registeredOut, const char* name)
strncpy((char*) &cmdbuf[1], name,8); strncpy((char*) &cmdbuf[1], name,8);
cmdbuf[3] = strnlen(name, 8); cmdbuf[3] = strnlen(name, 8);
if(R_FAILED(rc = svcSendSyncRequest(srvHandle)))return rc; rc = svcSendSyncRequest(srvHandle);
rc = R_SUCCEEDED(rc) ? cmdbuf[1] : rc;
if(registeredOut) *registeredOut = cmdbuf[2] & 0xFF; if(registeredOut) *registeredOut = R_SUCCEEDED(rc) && (cmdbuf[2] & 0xFF) != 0;
return cmdbuf[1]; return rc;
} }
Result srvIsPortRegistered(bool* registeredOut, const char* name) Result srvIsPortRegistered(bool* registeredOut, const char* name)