mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-13 09:39:33 +01:00
Ad hoc, PMP: Bound guest-sized buffers and lists
- Game mode master and replica data was copied by the game's size after checking one byte, into host buffers allocated by that size (up to 2 GB). If the copy failed, the uninitialized buffer was sent to peers. - sceNetAdhocctlCreateEnterGameMode read up to 16 member MACs after checking one byte. - sceNetAdhocMatchingCreate allocated and cleared the game's receive buffer size on the host with no upper bound. Cap it at 1 MB. - PMP video walked its block descriptors with only the first one checked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
917607d8fa
commit
f4b99a6a99
3 files changed
+14
-2
No files matched your search
@@ -962,6 +962,9 @@ static bool decodePmpVideo(PSPPointer<SceMpegRingBuffer> ringbuffer, u32 pmpctxA
|
||||
// joint all blocks into H264Frames
|
||||
for (int i = 0; i < pmp_nBlocks; i++){
|
||||
auto lli = PSPPointer<SceMpegLLI>::Create(pmp_videoSource);
|
||||
// Each block descriptor is in game memory, after the first.
|
||||
if (!lli.IsValid())
|
||||
break;
|
||||
// add source block into pmpframes
|
||||
const uint8_t *ptr = Memory::GetPointerRangeOrException(lli->pSrc, lli->iSize);
|
||||
if (ptr)
|
||||
|
||||
@@ -3391,6 +3391,9 @@ int NetAdhocctl_CreateEnterGameMode(const char* group_name, int game_type, int n
|
||||
|
||||
if (game_type < ADHOCCTL_GAMETYPE_1A || game_type > ADHOCCTL_GAMETYPE_2A || num_members < 2 || num_members > 16 || (game_type == ADHOCCTL_GAMETYPE_1A && num_members > 4))
|
||||
return SCE_NET_ADHOCCTL_ERROR_INVALID_ARG;
|
||||
// The whole member list is read below.
|
||||
if (!Memory::IsValidRange(membersAddr, num_members * (u32)sizeof(SceNetEtherAddr)))
|
||||
return SCE_NET_ADHOCCTL_ERROR_INVALID_ARG;
|
||||
|
||||
// In a normal group, it reports ALREADY_CONNECTED through the handlers and stays in it
|
||||
// (pspautotests net/adhoc/gamemode).
|
||||
@@ -4615,7 +4618,8 @@ static int sceNetAdhocGameModeCreateMaster(MIPSState *mips, u32 dataAddr, int si
|
||||
if (!netAdhocGameModeEntered)
|
||||
return hleLogError(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_NOT_ENTER_GAMEMODE, "not enter gamemode");
|
||||
|
||||
if (size < 0 || !Memory::IsValidAddress(dataAddr))
|
||||
// The data is copied (and the buffers are sized) by size.
|
||||
if (size < 0 || !Memory::IsValidAddress(dataAddr) || !Memory::IsValidRange(dataAddr, (u32)size))
|
||||
return hleLogError(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_INVALID_ARG, "invalid arg");
|
||||
|
||||
// pspautotests net/adhoc/pair/gamemode
|
||||
@@ -4672,7 +4676,7 @@ static int sceNetAdhocGameModeCreateReplica(MIPSState *mips, const char *mac, u3
|
||||
if (!netAdhocGameModeEntered)
|
||||
return hleLogError(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_NOT_ENTER_GAMEMODE, "not enter gamemode");
|
||||
|
||||
if (mac == nullptr || size < 0 || !Memory::IsValidAddress(dataAddr))
|
||||
if (mac == nullptr || size < 0 || !Memory::IsValidAddress(dataAddr) || !Memory::IsValidRange(dataAddr, (u32)size))
|
||||
return hleLogError(Log::sceNet, SCE_NET_ADHOCCTL_ERROR_INVALID_ARG, "invalid arg");
|
||||
|
||||
const SceNetEtherAddr &replicaMac = *(const SceNetEtherAddr *)mac;
|
||||
|
||||
@@ -1576,6 +1576,11 @@ static int sceNetAdhocMatchingCreate(MIPSState *mips, int mode, int maxnum, int
|
||||
// Invalid Receive Buffer Size
|
||||
return hleLogError(Log::sceNet, SCE_NET_ADHOC_MATCHING_ERROR_RXBUF_TOO_SHORT, "adhoc matching rxbuf too short");
|
||||
}
|
||||
// We allocate (and clear) this on the host. The PSP takes it from the library's small heap, and
|
||||
// no packet is anywhere near this big.
|
||||
if (rxbuflen > 1024 * 1024) {
|
||||
return hleLogError(Log::sceNet, SCE_NET_ADHOC_MATCHING_ERROR_NO_SPACE, "adhoc matching rxbuf too large");
|
||||
}
|
||||
|
||||
if (mode < 1 || mode > 3) {
|
||||
return hleLogError(Log::sceNet, SCE_NET_ADHOC_MATCHING_ERROR_INVALID_MODE, "adhoc matching invalid mode");
|
||||
|
||||
Reference in new issue
Block a user