From 8772c6e2f8a2148da241140529b61d287bd0b77d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 20 Sep 2022 00:31:01 -0700 Subject: [PATCH] Kernel: Check sceKernelAllocPartitionMemory args. This is the order you get error codes back in if there are multiple errors. --- Core/HLE/sceKernelMemory.cpp | 79 ++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 35 deletions(-) diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index f76658425f..4bbc7ac767 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -504,6 +504,31 @@ void __KernelMemoryShutdown() MemBlockInfoShutdown(); } +static BlockAllocator *BlockAllocatorFromID(int id) { + switch (id) { + case 1: + case 3: + case 4: + if (hleIsKernelMode()) + return &kernelMemory; + return nullptr; + + case 2: + case 6: + case 8: + case 10: + return &userMemory; + + case 5: + return &volatileMemory; + + default: + break; + } + + return nullptr; +} + enum SceKernelFplAttr { PSP_FPL_ATTR_FIFO = 0x0000, @@ -995,44 +1020,28 @@ static u32 sceKernelTotalFreeMemSize() return retVal; } -int sceKernelAllocPartitionMemory(int partition, const char *name, int type, u32 size, u32 addr) -{ - if (name == NULL) - { - WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelAllocPartitionMemory(): invalid name", SCE_KERNEL_ERROR_ERROR); - return SCE_KERNEL_ERROR_ERROR; - } - if (size == 0) - { - WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelAllocPartitionMemory(): invalid size %x", SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED, size); - return SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED; +int sceKernelAllocPartitionMemory(int partition, const char *name, int type, u32 size, u32 addr) { + if (type < PSP_SMEM_Low || type > PSP_SMEM_HighAligned) + return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCKTYPE, "invalid type %x", type); + // Alignment is only allowed for powers of 2. + if (type == PSP_SMEM_LowAligned || type == PSP_SMEM_HighAligned) { + if ((addr & (addr - 1)) != 0 || addr == 0) + return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ALIGNMENT_SIZE, "invalid alignment %x", addr); } if (partition < 1 || partition > 9 || partition == 7) - { - WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelAllocPartitionMemory(): invalid partition %x", SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, partition); - return SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT; - } - // We only support user right now. - if (partition != 2 && partition != 5 && partition != 6) - { - WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelAllocPartitionMemory(): invalid partition %x", SCE_KERNEL_ERROR_ILLEGAL_PARTITION, partition); - return SCE_KERNEL_ERROR_ILLEGAL_PARTITION; - } - if (type < PSP_SMEM_Low || type > PSP_SMEM_HighAligned) - { - WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelAllocPartitionMemory(): invalid type %x", SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCKTYPE, type); - return SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCKTYPE; - } - // Alignment is only allowed for powers of 2. - if ((type == PSP_SMEM_LowAligned || type == PSP_SMEM_HighAligned) && ((addr & (addr - 1)) != 0 || addr == 0)) - { - WARN_LOG_REPORT(SCEKERNEL, "%08x=sceKernelAllocPartitionMemory(): invalid alignment %x", SCE_KERNEL_ERROR_ILLEGAL_ALIGNMENT_SIZE, addr); - return SCE_KERNEL_ERROR_ILLEGAL_ALIGNMENT_SIZE; - } + return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, "invalid partition %x", partition); - PartitionMemoryBlock *block = new PartitionMemoryBlock((partition == 5) ? &volatileMemory : &userMemory, name, size, (MemblockType)type, addr); - if (!block->IsValid()) - { + BlockAllocator *allocator = BlockAllocatorFromID(partition); + if (allocator == nullptr) + return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_ILLEGAL_PARTITION, "invalid partition %x", partition); + + if (name == nullptr) + return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_ERROR, "invalid name"); + if (size == 0) + return hleLogWarning(SCEKERNEL, SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED, "invalid size %x", size); + + PartitionMemoryBlock *block = new PartitionMemoryBlock(allocator, name, size, (MemblockType)type, addr); + if (!block->IsValid()) { delete block; ERROR_LOG(SCEKERNEL, "sceKernelAllocPartitionMemory(partition = %i, %s, type= %i, size= %i, addr= %08x): allocation failed", partition, name, type, size, addr); return SCE_KERNEL_ERROR_MEMBLOCK_ALLOC_FAILED;