Add safety checks for loaded FIRM modules
This commit is contained in:
parent
a0531b7930
commit
62f7a06192
@ -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();
|
initScreens();
|
||||||
clearScreens(true, true, true);
|
clearScreens(true, true, true);
|
||||||
|
|
||||||
if(isTopSplashValid) fileRead(fbs[1].top_left, topSplashFile, SCREEN_TOP_FBSIZE);
|
if(isTopSplashValid) isTopSplashValid = fileRead(fbs[1].top_left, topSplashFile, SCREEN_TOP_FBSIZE) == SCREEN_TOP_FBSIZE;
|
||||||
if(isBottomSplashValid) fileRead(fbs[1].bottom, bottomSplashFile, SCREEN_BOTTOM_FBSIZE);
|
if(isBottomSplashValid) isBottomSplashValid = fileRead(fbs[1].bottom, bottomSplashFile, SCREEN_BOTTOM_FBSIZE) == SCREEN_BOTTOM_FBSIZE;
|
||||||
|
|
||||||
|
if(!isTopSplashValid && !isBottomSplashValid) ret = false;
|
||||||
|
else
|
||||||
|
{
|
||||||
swapFramebuffers(true);
|
swapFramebuffers(true);
|
||||||
|
|
||||||
chrono(3);
|
chrono(3);
|
||||||
|
|
||||||
return true;
|
ret = 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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,10 +139,13 @@ 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);
|
|
||||||
|
if(fileRead(message, messageFile, messageSize) == messageSize)
|
||||||
|
{
|
||||||
message[messageSize] = 0;
|
message[messageSize] = 0;
|
||||||
drawString(message, false, 10, 10, COLOR_WHITE);
|
drawString(message, false, 10, 10, COLOR_WHITE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while(!unlock)
|
while(!unlock)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user