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";
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
if(!isTopSplashValid && !isBottomSplashValid)
return false;
if(!isTopSplashValid && !isBottomSplashValid) ret = false;
else
{
initScreens();
clearScreens(true, true, true);
initScreens();
clearScreens(true, true, true);
if(isTopSplashValid) isTopSplashValid = fileRead(fbs[1].top_left, topSplashFile, SCREEN_TOP_FBSIZE) == SCREEN_TOP_FBSIZE;
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(isBottomSplashValid) fileRead(fbs[1].bottom, bottomSplashFile, SCREEN_BOTTOM_FBSIZE);
if(!isTopSplashValid && !isBottomSplashValid) ret = false;
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)

View File

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

View File

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