From ffaa5790c23f3b03ae1b12b07d670d5f9f4bca4c Mon Sep 17 00:00:00 2001 From: Aurora Date: Tue, 13 Sep 2016 14:54:14 +0200 Subject: [PATCH] Cleanup, add boundary checks for files loaded from SD --- source/config.c | 10 +++++----- source/draw.c | 30 ++++++++++++++++++------------ source/draw.h | 12 +++++++----- source/exceptions.c | 4 ++-- source/firm.c | 10 +++++----- source/fs.c | 37 +++++++++++++++++++++---------------- source/fs.h | 2 +- source/pin.c | 2 +- source/screen.c | 6 +++--- source/strings.c | 8 ++++---- source/strings.h | 4 ++-- source/utils.c | 2 +- 12 files changed, 70 insertions(+), 57 deletions(-) diff --git a/source/config.c b/source/config.c index a0b6855..0c23b8a 100644 --- a/source/config.c +++ b/source/config.c @@ -31,7 +31,7 @@ bool readConfig(void) { - if(fileRead(&configData, CONFIG_PATH) != sizeof(CfgData) || + if(fileRead(&configData, CONFIG_PATH, sizeof(CfgData)) != sizeof(CfgData) || memcmp(configData.magic, "CONF", 4) != 0 || configData.formatVersionMajor != CONFIG_VERSIONMAJOR || configData.formatVersionMinor != CONFIG_VERSIONMINOR) @@ -87,8 +87,8 @@ void configMenu(bool oldPinStatus) }; struct multiOption { - int posXs[4]; - int posY; + u32 posXs[4]; + u32 posY; u32 enabled; } multiOptions[] = { { .posXs = {19, 24, 29, 34} }, @@ -107,7 +107,7 @@ void configMenu(bool oldPinStatus) selectedOption = multiOptionsAmount; struct singleOption { - int posY; + u32 posY; bool enabled; } singleOptions[singleOptionsAmount]; @@ -125,7 +125,7 @@ void configMenu(bool oldPinStatus) //Character to display a selected option char selected = 'x'; - int endPos = 42; + u32 endPos = 42; //Display all the multiple choice options in white for(u32 i = 0; i < multiOptionsAmount; i++) diff --git a/source/draw.c b/source/draw.c index db59086..23da7e8 100644 --- a/source/draw.c +++ b/source/draw.c @@ -36,14 +36,20 @@ static bool bottomScreenSelected = false; bool loadSplash(void) { - //Don't delay boot nor init the screens if no splash image is on the SD - if(getFileSize("/luma/splash.bin") + getFileSize("/luma/splashbottom.bin") == 0) + u32 topSplashSize = getFileSize("/luma/splash.bin"), + bottomSplashSize = getFileSize("/luma/splashbottom.bin"); + + bool isTopSplashValid = topSplashSize == SCREEN_TOP_FBSIZE, + isBottomSplashValid = bottomSplashSize == SCREEN_BOTTOM_FBSIZE; + + //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; - + initScreens(); - fileRead(fb->top_left, "/luma/splash.bin"); - fileRead(fb->bottom, "/luma/splashbottom.bin"); + if(isTopSplashValid) fileRead(fb->top_left, "/luma/splash.bin", topSplashSize); + if(isBottomSplashValid) fileRead(fb->bottom, "/luma/splashbottom.bin", bottomSplashSize); chrono(3); @@ -55,18 +61,18 @@ void selectScreen(bool isBottomScreen) bottomScreenSelected = isBottomScreen; } -void drawCharacter(char character, int posX, int posY, u32 color) +void drawCharacter(char character, u32 posX, u32 posY, u32 color) { u8 *const select = bottomScreenSelected ? fb->bottom : fb->top_left; - for(int y = 0; y < 8; y++) + for(u32 y = 0; y < 8; y++) { char charPos = font[character * 8 + y]; - for(int x = 7; x >= 0; x--) - if((charPos >> x) & 1) + for(u32 x = 0; x < 8; x++) + if((charPos >> (7 - x)) & 1) { - int screenPos = (posX * SCREEN_HEIGHT * 3 + (SCREEN_HEIGHT - y - posY - 1) * 3) + (7 - x) * 3 * SCREEN_HEIGHT; + u32 screenPos = (posX * SCREEN_HEIGHT * 3 + (SCREEN_HEIGHT - y - posY - 1) * 3) + x * 3 * SCREEN_HEIGHT; select[screenPos] = color >> 16; select[screenPos + 1] = color >> 8; @@ -75,9 +81,9 @@ void drawCharacter(char character, int posX, int posY, u32 color) } } -int drawString(const char *string, int posX, int posY, u32 color) +u32 drawString(const char *string, u32 posX, u32 posY, u32 color) { - for(int i = 0, line_i = 0; i < strlen(string); i++, line_i++) + for(u32 i = 0, line_i = 0; i < strlen(string); i++, line_i++) { if(string[i] == '\n') { diff --git a/source/draw.h b/source/draw.h index 61aadf6..6466618 100644 --- a/source/draw.h +++ b/source/draw.h @@ -29,9 +29,11 @@ #include "types.h" -#define SCREEN_TOP_WIDTH 400 -#define SCREEN_BOTTOM_WIDTH 320 -#define SCREEN_HEIGHT 240 +#define SCREEN_TOP_WIDTH 400 +#define SCREEN_BOTTOM_WIDTH 320 +#define SCREEN_HEIGHT 240 +#define SCREEN_TOP_FBSIZE (3 * SCREEN_TOP_WIDTH * SCREEN_HEIGHT) +#define SCREEN_BOTTOM_FBSIZE (3 * SCREEN_BOTTOM_WIDTH * SCREEN_HEIGHT) #define SPACING_Y 10 #define SPACING_X 8 @@ -44,5 +46,5 @@ bool loadSplash(void); void selectScreen(bool isBottomScreen); -void drawCharacter(char character, int posX, int posY, u32 color); -int drawString(const char *string, int posX, int posY, u32 color); \ No newline at end of file +void drawCharacter(char character, u32 posX, u32 posY, u32 color); +u32 drawString(const char *string, u32 posX, u32 posY, u32 color); \ No newline at end of file diff --git a/source/exceptions.c b/source/exceptions.c index 6ee8406..e21ff9c 100644 --- a/source/exceptions.c +++ b/source/exceptions.c @@ -108,7 +108,7 @@ void detectAndProcessExceptionDumps(void) initScreens(); drawString("An exception occurred", 10, 10, COLOR_RED); - int posY = drawString(dumpHeader->processor == 11 ? "Processor: ARM11 (core )" : "Processor: ARM9", 10, 30, COLOR_WHITE); + u32 posY = drawString(dumpHeader->processor == 11 ? "Processor: ARM11 (core )" : "Processor: ARM9", 10, 30, COLOR_WHITE); if(dumpHeader->processor == 11) drawCharacter('0' + dumpHeader->core, 10 + 29 * SPACING_X, 30, COLOR_WHITE); posY = drawString("Exception type: ", 10, posY + SPACING_Y, COLOR_WHITE); @@ -160,7 +160,7 @@ void detectAndProcessExceptionDumps(void) selectScreen(true); - int posYBottom = drawString("Stack dump:", 10, 10, COLOR_WHITE) + SPACING_Y; + u32 posYBottom = drawString("Stack dump:", 10, 10, COLOR_WHITE) + SPACING_Y; for(u32 line = 0; line < 19 && stackDump < additionalData; line++) { diff --git a/source/firm.c b/source/firm.c index d0d5ec7..0b08422 100755 --- a/source/firm.c +++ b/source/firm.c @@ -294,12 +294,12 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource) } //Check that the SD FIRM is right for the console from the ARM9 section address - if(fileRead(firm, *firmType == NATIVE_FIRM1X2X ? firmwareFiles[0] : firmwareFiles[(u32)*firmType]) && + if(fileRead(firm, *firmType == NATIVE_FIRM1X2X ? firmwareFiles[0] : firmwareFiles[(u32)*firmType], 0x400000) && ((section[3].offset ? section[3].address : section[2].address) == (isN3DS ? (u8 *)0x8006000 : (u8 *)0x8006800))) firmVersion = 0xFFFFFFFF; else { - if(loadFromSd) error("An old unsupported FIRM has been detected.\nCopy firmware.bin in /luma to boot"); + if(loadFromSd) error("An old unsupported FIRM has been detected.\nCopy a valid firmware.bin in /luma to boot"); decryptExeFs((u8 *)firm); } @@ -329,8 +329,8 @@ static inline u32 loadFirm(FirmwareType *firmType, FirmwareSource firmSource) //We can't boot a 3.x/4.x NATIVE_FIRM, load one from SD else if(firmVersion < 0x25) { - if(!fileRead(firm, "/luma/firmware.bin") || section[2].address != (u8 *)0x8006800) - error("An old unsupported FIRM has been detected.\nCopy firmware.bin in /luma to boot"); + if(!fileRead(firm, "/luma/firmware.bin", 0x400000) || section[2].address != (u8 *)0x8006800) + error("An old unsupported FIRM has been detected.\nCopy a valid firmware.bin in /luma to boot"); //No assumption regarding FIRM version firmVersion = 0xFFFFFFFF; @@ -499,7 +499,7 @@ static inline void copySection0AndInjectSystemModules(FirmwareType firmType) concatenateStrings(fileName, moduleName); concatenateStrings(fileName, ext); - u32 fileSize = fileRead(dst, fileName); + u32 fileSize = fileRead(dst, fileName, 2 * srcModuleSize); if(fileSize) dstModuleSize = fileSize; else { diff --git a/source/fs.c b/source/fs.c index 8c93f84..74e6e21 100644 --- a/source/fs.c +++ b/source/fs.c @@ -38,27 +38,26 @@ void mountFs(void) f_mount(&nandFs, "1:", 0); } -u32 fileRead(void *dest, const char *path) +u32 fileRead(void *dest, const char *path, u32 maxSize) { FIL file; - u32 size; + u32 ret = 0; if(f_open(&file, path, FA_READ) == FR_OK) { - unsigned int read; - size = f_size(&file); - if(dest != NULL) - f_read(&file, dest, size, &read); + u32 size = f_size(&file); + if(dest == NULL) ret = size; + else if(!(maxSize > 0 && size > maxSize)) + f_read(&file, dest, size, (unsigned int *)&ret); f_close(&file); } - else size = 0; - return size; + return ret; } u32 getFileSize(const char *path) { - return fileRead(NULL, path); + return fileRead(NULL, path, 0); } bool fileWrite(const void *buffer, const char *path, u32 size) @@ -125,21 +124,27 @@ void loadPayload(u32 pressed) if(result == FR_OK && info.fname[0]) { - initScreens(); - u32 *loaderAddress = (u32 *)0x24FFFF00; + u8 *payloadAddress = (u8 *)0x24F00000; memcpy(loaderAddress, loader, loader_size); concatenateStrings(path, "/"); concatenateStrings(path, info.altname); - loaderAddress[1] = fileRead((void *)0x24F00000, path); + u32 payloadSize = fileRead(payloadAddress, path, (u8 *)loaderAddress - payloadAddress); - flushDCacheRange(loaderAddress, loader_size); - flushICacheRange(loaderAddress, loader_size); + if(payloadSize > 0) + { + loaderAddress[1] = payloadSize; - ((void (*)())loaderAddress)(); + initScreens(); + + flushDCacheRange(loaderAddress, loader_size); + flushICacheRange(loaderAddress, loader_size); + + ((void (*)())loaderAddress)(); + } } } @@ -187,7 +192,7 @@ u32 firmRead(void *dest, u32 firmType) //Convert back the .app name from integer to array hexItoa(firmVersion, &path[35], 8); - fileRead(dest, path); + fileRead(dest, path, 0); return firmVersion; } diff --git a/source/fs.h b/source/fs.h index 61c9f1b..4c8fb93 100644 --- a/source/fs.h +++ b/source/fs.h @@ -29,7 +29,7 @@ extern bool isN3DS; void mountFs(void); -u32 fileRead(void *dest, const char *path); +u32 fileRead(void *dest, const char *path, u32 maxSize); u32 getFileSize(const char *path); bool fileWrite(const void *buffer, const char *path, u32 size); void fileDelete(const char *path); diff --git a/source/pin.c b/source/pin.c index 58c9232..feae9fe 100644 --- a/source/pin.c +++ b/source/pin.c @@ -108,7 +108,7 @@ bool verifyPin(void) { PinData pin; - if(fileRead(&pin, PIN_PATH) != sizeof(PinData) || + if(fileRead(&pin, PIN_PATH, sizeof(PinData)) != sizeof(PinData) || memcmp(pin.magic, "PINF", 4) != 0 || pin.formatVersionMajor != PIN_VERSIONMAJOR || pin.formatVersionMinor != PIN_VERSIONMINOR || diff --git a/source/screen.c b/source/screen.c index 89831f7..a138804 100644 --- a/source/screen.c +++ b/source/screen.c @@ -111,13 +111,13 @@ void clearScreens(void) //Setting up two simultaneous memory fills using the GPU vu32 *REGs_PSC0 = (vu32 *)0x10400010; REGs_PSC0[0] = (u32)fb->top_left >> 3; //Start address - REGs_PSC0[1] = (u32)(fb->top_left + 0x46500) >> 3; //End address + REGs_PSC0[1] = (u32)(fb->top_left + SCREEN_TOP_FBSIZE) >> 3; //End address REGs_PSC0[2] = 0; //Fill value REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start vu32 *REGs_PSC1 = (vu32 *)0x10400020; REGs_PSC1[0] = (u32)fb->bottom >> 3; //Start address - REGs_PSC1[1] = (u32)(fb->bottom + 0x38400) >> 3; //End address + REGs_PSC1[1] = (u32)(fb->bottom + SCREEN_BOTTOM_FBSIZE) >> 3; //End address REGs_PSC1[2] = 0; //Fill value REGs_PSC1[3] = (2 << 8) | 1; //32-bit pattern; start @@ -126,7 +126,7 @@ void clearScreens(void) if(fb->top_right != fb->top_left) { REGs_PSC0[0] = (u32)fb->top_right >> 3; //Start address - REGs_PSC0[1] = (u32)(fb->top_right + 0x46500) >> 3; //End address + REGs_PSC0[1] = (u32)(fb->top_right + SCREEN_TOP_FBSIZE) >> 3; //End address REGs_PSC0[2] = 0; //Fill value REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start diff --git a/source/strings.c b/source/strings.c index 552cbe5..86e93ce 100644 --- a/source/strings.c +++ b/source/strings.c @@ -23,7 +23,7 @@ #include "strings.h" #include "memory.h" -int strlen(const char *string) +u32 strlen(const char *string) { char *stringEnd = (char *)string; @@ -40,16 +40,16 @@ void concatenateStrings(char *destination, const char *source) memcpy(&destination[j], source, i + 1); } -void hexItoa(u32 number, char *out, u32 nbDigits) +void hexItoa(u32 number, char *out, u32 digits) { const char hexDigits[] = "0123456789ABCDEF"; u32 i = 0; while(number > 0) { - out[nbDigits - 1 - i++] = hexDigits[number & 0xF]; + out[digits - 1 - i++] = hexDigits[number & 0xF]; number >>= 4; } - for(; i < nbDigits; i++) out[nbDigits - 1 - i] = '0'; + for(; i < digits; i++) out[digits - 1 - i] = '0'; } \ No newline at end of file diff --git a/source/strings.h b/source/strings.h index 6a7ee4a..fc40e19 100644 --- a/source/strings.h +++ b/source/strings.h @@ -24,6 +24,6 @@ #include "types.h" -int strlen(const char *string); +u32 strlen(const char *string); void concatenateStrings(char *destination, const char *source); -void hexItoa(u32 number, char *out, u32 nbDigits); \ No newline at end of file +void hexItoa(u32 number, char *out, u32 digits); \ No newline at end of file diff --git a/source/utils.c b/source/utils.c index af73006..51093a4 100644 --- a/source/utils.c +++ b/source/utils.c @@ -116,7 +116,7 @@ void error(const char *message) initScreens(); drawString("An error has occurred:", 10, 10, COLOR_RED); - int posY = drawString(message, 10, 30, COLOR_WHITE); + u32 posY = drawString(message, 10, 30, COLOR_WHITE); drawString("Press any button to shutdown", 10, posY + 2 * SPACING_Y, COLOR_WHITE); waitInput();