Add safety checks for loaded FIRM modules

This commit is contained in:
Aurora 2016-10-16 02:47:53 +02:00
parent a0531b7930
commit 62f7a06192
3 changed files with 48 additions and 22 deletions

View File

@ -38,23 +38,31 @@ bool loadSplash(void)
*bottomSplashFile = "splashbottom.bin"; *bottomSplashFile = "splashbottom.bin";
bool isTopSplashValid = getFileSize(topSplashFile) == SCREEN_TOP_FBSIZE, bool isTopSplashValid = getFileSize(topSplashFile) == SCREEN_TOP_FBSIZE,
isBottomSplashValid = getFileSize(bottomSplashFile) == SCREEN_BOTTOM_FBSIZE; isBottomSplashValid = getFileSize(bottomSplashFile) == SCREEN_BOTTOM_FBSIZE,
ret;
//Don't delay boot nor init the screens if no splash images or invalid splash images are on the SD //Don't delay boot nor init the screens if no splash images or invalid splash images are on the SD
if(!isTopSplashValid && !isBottomSplashValid) if(!isTopSplashValid && !isBottomSplashValid) ret = false;
return false; else
{
initScreens();
clearScreens(true, true, true);
initScreens(); if(isTopSplashValid) isTopSplashValid = fileRead(fbs[1].top_left, topSplashFile, SCREEN_TOP_FBSIZE) == SCREEN_TOP_FBSIZE;
clearScreens(true, true, true); if(isBottomSplashValid) isBottomSplashValid = fileRead(fbs[1].bottom, bottomSplashFile, SCREEN_BOTTOM_FBSIZE) == SCREEN_BOTTOM_FBSIZE;
if(isTopSplashValid) fileRead(fbs[1].top_left, topSplashFile, SCREEN_TOP_FBSIZE); if(!isTopSplashValid && !isBottomSplashValid) ret = false;
if(isBottomSplashValid) fileRead(fbs[1].bottom, bottomSplashFile, SCREEN_BOTTOM_FBSIZE); else
{
swapFramebuffers(true);
swapFramebuffers(true); chrono(3);
chrono(3); ret = true;
}
}
return true; return ret;
} }
void drawCharacter(char character, bool isTopScreen, u32 posX, u32 posY, u32 color) void drawCharacter(char character, bool isTopScreen, u32 posX, u32 posY, u32 color)

View File

@ -285,18 +285,20 @@ u32 patch1x2xNativeAndSafeFirm(u32 devMode)
static inline void copySection0AndInjectSystemModules(FirmwareType firmType, bool loadFromStorage) static inline void copySection0AndInjectSystemModules(FirmwareType firmType, bool loadFromStorage)
{ {
u32 srcModuleSize, u32 maxModuleSize = firmType == NATIVE_FIRM ? 0x80000 : 0x600000,
srcModuleSize,
dstModuleSize; dstModuleSize;
for(u8 *src = (u8 *)firm + firm->section[0].offset, *srcEnd = src + firm->section[0].size, *dst = firm->section[0].address; for(u8 *src = (u8 *)firm + firm->section[0].offset, *srcEnd = src + firm->section[0].size, *dst = firm->section[0].address;
src < srcEnd; src += srcModuleSize, dst += dstModuleSize) src < srcEnd; src += srcModuleSize, dst += dstModuleSize, maxModuleSize -= dstModuleSize)
{ {
srcModuleSize = ((Cxi *)src)->ncch.contentSize * 0x200; srcModuleSize = ((Cxi *)src)->ncch.contentSize * 0x200;
const char *moduleName = ((Cxi *)src)->exHeader.systemControlInfo.appTitle; const char *moduleName = ((Cxi *)src)->exHeader.systemControlInfo.appTitle;
u32 fileSize; bool loadedModule;
if(loadFromStorage) if(!loadFromStorage) loadedModule = false;
else
{ {
char fileName[24] = "sysmodules/"; char fileName[24] = "sysmodules/";
const char *ext = ".cxi"; const char *ext = ".cxi";
@ -305,12 +307,23 @@ static inline void copySection0AndInjectSystemModules(FirmwareType firmType, boo
concatenateStrings(fileName, moduleName); concatenateStrings(fileName, moduleName);
concatenateStrings(fileName, ext); concatenateStrings(fileName, ext);
fileSize = fileRead(dst, fileName, 2 * srcModuleSize); dstModuleSize = getFileSize(fileName);
}
else fileSize = 0;
if(fileSize > 0) dstModuleSize = fileSize; if(dstModuleSize == 0) loadedModule = false;
else else
{
if(dstModuleSize <= sizeof(Cxi) + 0x200 ||
dstModuleSize > maxModuleSize ||
fileRead(dst, fileName, dstModuleSize) != dstModuleSize ||
memcmp(((Cxi *)dst)->ncch.magic, "NCCH", 4) != 0 ||
memcmp(moduleName, ((Cxi *)dst)->exHeader.systemControlInfo.appTitle, sizeof(((Cxi *)dst)->exHeader.systemControlInfo.appTitle)) != 0)
error("An external FIRM module is invalid.");
loadedModule = true;
}
}
if(!loadedModule)
{ {
const u8 *module; const u8 *module;
@ -325,6 +338,8 @@ static inline void copySection0AndInjectSystemModules(FirmwareType firmType, boo
dstModuleSize = srcModuleSize; dstModuleSize = srcModuleSize;
} }
if(dstModuleSize > maxModuleSize) error("The FIRM modules section is full.");
memcpy(dst, module, dstModuleSize); memcpy(dst, module, dstModuleSize);
} }
} }

View File

@ -139,9 +139,12 @@ bool verifyPin(u32 pinMode)
if(messageSize > 0 && messageSize <= 800) if(messageSize > 0 && messageSize <= 800)
{ {
char message[messageSize + 1]; char message[messageSize + 1];
fileRead(message, messageFile, messageSize);
message[messageSize] = 0; if(fileRead(message, messageFile, messageSize) == messageSize)
drawString(message, false, 10, 10, COLOR_WHITE); {
message[messageSize] = 0;
drawString(message, false, 10, 10, COLOR_WHITE);
}
} }
while(!unlock) while(!unlock)