mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-01 03:57:17 +01:00
HLE: Check more guest buffers by their full length, and an empty insert
Calls that checked one byte of a game's buffer and then wrote or read the whole thing, or trusted a negative length: - sceNetEtherNtostr/Strton, the apctl BSS descriptor calls, GetState and sceNetGetDropRate. - sceNpAuthGetTicket wrote its whole ticket whatever the length; it's now built locally and written once the buffer is known to hold it. sceNpAuthGetTicketParam checked its limits after copying, and walked ticket params past the ticket's end. - sceNp2's communication ID and passphrase, a negative maxServerIds, and an unchecked unknown1Ptr. - sceParseUri's work area and scheme string, sceParseHttp's negative header length and value address, and ReadVariableSizedStruct's size. - sceKernelCreateLwMutex initialized the work area without checking it at all, and the other LwMutex calls checked one byte of it. - sceNetAdhocctlGetScanInfo cleared the length the game gave, of a buffer checked by one byte (or any length, negative ones included). Also: a game mode join inserted at begin() + 1 into a possibly empty list of players. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c0e750726f
commit
0a778a13ff
9 files changed
+127
-67
No files matched your search
@@ -40,10 +40,11 @@ std::string getHeaderString(std::istringstream &headers) {
|
||||
|
||||
// FIXME: Is it allowed for fieldName to be null/0 or empty string ? JPCSP seems to ignore it
|
||||
static int sceParseHttpResponseHeader(u32 headerAddr, int headerLength, const char *fieldName, u32 valueAddr, u32 valueLengthAddr) {
|
||||
if (!Memory::IsValidRange(headerAddr, headerLength))
|
||||
if (headerLength < 0 || !Memory::IsValidRange(headerAddr, headerLength))
|
||||
return hleLogError(Log::sceNet, -1, "invalid arg");
|
||||
|
||||
if (!Memory::IsValidRange(valueLengthAddr, 4))
|
||||
// The value's address gets written to valueAddr.
|
||||
if (!Memory::IsValidRange(valueLengthAddr, 4) || !Memory::IsValidRange(valueAddr, 4))
|
||||
return hleLogError(Log::sceNet, -1, "invalid arg");
|
||||
|
||||
// FIXME: Not sure whether valueAddr can be null or not (in case the game just need to get the size to allocate the value buffer first)
|
||||
@@ -53,7 +54,7 @@ static int sceParseHttpResponseHeader(u32 headerAddr, int headerLength, const ch
|
||||
|
||||
std::string field = fieldName ? fieldName : "";
|
||||
field = StripSpaces(field);
|
||||
std::string headers(Memory::GetCharPointer(headerAddr), headerLength);
|
||||
std::string headers = headerLength > 0 ? std::string(Memory::GetCharPointerUnchecked(headerAddr), headerLength) : std::string();
|
||||
std::istringstream hdrs(headers);
|
||||
u32 addr = 0;
|
||||
u32 len = 0;
|
||||
@@ -108,7 +109,7 @@ static int sceParseHttpStatusLine(MIPSState *mips, u32 headerAddr, u32 headerLen
|
||||
if (!Memory::IsValidRange(headerAddr, headerLength))
|
||||
return hleLogError(Log::sceNet, -1, "invalid arg");
|
||||
|
||||
std::string headers(Memory::GetCharPointer(headerAddr), headerLength);
|
||||
std::string headers = headerLength > 0 ? std::string(Memory::GetCharPointerUnchecked(headerAddr), headerLength) : std::string();
|
||||
// Get first line from header, line ending can be '\n' or '\r'
|
||||
std::istringstream hdr(headers);
|
||||
std::string line;
|
||||
|
||||
Reference in new issue
Block a user