Cleanup, add boundary checks for files loaded from SD

This commit is contained in:
Aurora 2016-09-13 14:54:14 +02:00
parent 934c4bed0b
commit ffaa5790c2
12 changed files with 70 additions and 57 deletions

View File

@ -31,7 +31,7 @@
bool readConfig(void) 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 || memcmp(configData.magic, "CONF", 4) != 0 ||
configData.formatVersionMajor != CONFIG_VERSIONMAJOR || configData.formatVersionMajor != CONFIG_VERSIONMAJOR ||
configData.formatVersionMinor != CONFIG_VERSIONMINOR) configData.formatVersionMinor != CONFIG_VERSIONMINOR)
@ -87,8 +87,8 @@ void configMenu(bool oldPinStatus)
}; };
struct multiOption { struct multiOption {
int posXs[4]; u32 posXs[4];
int posY; u32 posY;
u32 enabled; u32 enabled;
} multiOptions[] = { } multiOptions[] = {
{ .posXs = {19, 24, 29, 34} }, { .posXs = {19, 24, 29, 34} },
@ -107,7 +107,7 @@ void configMenu(bool oldPinStatus)
selectedOption = multiOptionsAmount; selectedOption = multiOptionsAmount;
struct singleOption { struct singleOption {
int posY; u32 posY;
bool enabled; bool enabled;
} singleOptions[singleOptionsAmount]; } singleOptions[singleOptionsAmount];
@ -125,7 +125,7 @@ void configMenu(bool oldPinStatus)
//Character to display a selected option //Character to display a selected option
char selected = 'x'; char selected = 'x';
int endPos = 42; u32 endPos = 42;
//Display all the multiple choice options in white //Display all the multiple choice options in white
for(u32 i = 0; i < multiOptionsAmount; i++) for(u32 i = 0; i < multiOptionsAmount; i++)

View File

@ -36,14 +36,20 @@ static bool bottomScreenSelected = false;
bool loadSplash(void) bool loadSplash(void)
{ {
//Don't delay boot nor init the screens if no splash image is on the SD u32 topSplashSize = getFileSize("/luma/splash.bin"),
if(getFileSize("/luma/splash.bin") + getFileSize("/luma/splashbottom.bin") == 0) 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; return false;
initScreens(); initScreens();
fileRead(fb->top_left, "/luma/splash.bin"); if(isTopSplashValid) fileRead(fb->top_left, "/luma/splash.bin", topSplashSize);
fileRead(fb->bottom, "/luma/splashbottom.bin"); if(isBottomSplashValid) fileRead(fb->bottom, "/luma/splashbottom.bin", bottomSplashSize);
chrono(3); chrono(3);
@ -55,18 +61,18 @@ void selectScreen(bool isBottomScreen)
bottomScreenSelected = 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; 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]; char charPos = font[character * 8 + y];
for(int x = 7; x >= 0; x--) for(u32 x = 0; x < 8; x++)
if((charPos >> x) & 1) 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] = color >> 16;
select[screenPos + 1] = color >> 8; 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') if(string[i] == '\n')
{ {

View File

@ -32,6 +32,8 @@
#define SCREEN_TOP_WIDTH 400 #define SCREEN_TOP_WIDTH 400
#define SCREEN_BOTTOM_WIDTH 320 #define SCREEN_BOTTOM_WIDTH 320
#define SCREEN_HEIGHT 240 #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_Y 10
#define SPACING_X 8 #define SPACING_X 8
@ -44,5 +46,5 @@
bool loadSplash(void); bool loadSplash(void);
void selectScreen(bool isBottomScreen); void selectScreen(bool isBottomScreen);
void drawCharacter(char character, int posX, int posY, u32 color); void drawCharacter(char character, u32 posX, u32 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);

View File

@ -108,7 +108,7 @@ void detectAndProcessExceptionDumps(void)
initScreens(); initScreens();
drawString("An exception occurred", 10, 10, COLOR_RED); 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); 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); posY = drawString("Exception type: ", 10, posY + SPACING_Y, COLOR_WHITE);
@ -160,7 +160,7 @@ void detectAndProcessExceptionDumps(void)
selectScreen(true); 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++) for(u32 line = 0; line < 19 && stackDump < additionalData; line++)
{ {

View File

@ -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 //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))) ((section[3].offset ? section[3].address : section[2].address) == (isN3DS ? (u8 *)0x8006000 : (u8 *)0x8006800)))
firmVersion = 0xFFFFFFFF; firmVersion = 0xFFFFFFFF;
else 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); 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 //We can't boot a 3.x/4.x NATIVE_FIRM, load one from SD
else if(firmVersion < 0x25) else if(firmVersion < 0x25)
{ {
if(!fileRead(firm, "/luma/firmware.bin") || section[2].address != (u8 *)0x8006800) if(!fileRead(firm, "/luma/firmware.bin", 0x400000) || section[2].address != (u8 *)0x8006800)
error("An old unsupported FIRM has been detected.\nCopy firmware.bin in /luma to boot"); error("An old unsupported FIRM has been detected.\nCopy a valid firmware.bin in /luma to boot");
//No assumption regarding FIRM version //No assumption regarding FIRM version
firmVersion = 0xFFFFFFFF; firmVersion = 0xFFFFFFFF;
@ -499,7 +499,7 @@ static inline void copySection0AndInjectSystemModules(FirmwareType firmType)
concatenateStrings(fileName, moduleName); concatenateStrings(fileName, moduleName);
concatenateStrings(fileName, ext); concatenateStrings(fileName, ext);
u32 fileSize = fileRead(dst, fileName); u32 fileSize = fileRead(dst, fileName, 2 * srcModuleSize);
if(fileSize) dstModuleSize = fileSize; if(fileSize) dstModuleSize = fileSize;
else else
{ {

View File

@ -38,27 +38,26 @@ void mountFs(void)
f_mount(&nandFs, "1:", 0); f_mount(&nandFs, "1:", 0);
} }
u32 fileRead(void *dest, const char *path) u32 fileRead(void *dest, const char *path, u32 maxSize)
{ {
FIL file; FIL file;
u32 size; u32 ret = 0;
if(f_open(&file, path, FA_READ) == FR_OK) if(f_open(&file, path, FA_READ) == FR_OK)
{ {
unsigned int read; u32 size = f_size(&file);
size = f_size(&file); if(dest == NULL) ret = size;
if(dest != NULL) else if(!(maxSize > 0 && size > maxSize))
f_read(&file, dest, size, &read); f_read(&file, dest, size, (unsigned int *)&ret);
f_close(&file); f_close(&file);
} }
else size = 0;
return size; return ret;
} }
u32 getFileSize(const char *path) u32 getFileSize(const char *path)
{ {
return fileRead(NULL, path); return fileRead(NULL, path, 0);
} }
bool fileWrite(const void *buffer, const char *path, u32 size) bool fileWrite(const void *buffer, const char *path, u32 size)
@ -125,16 +124,21 @@ void loadPayload(u32 pressed)
if(result == FR_OK && info.fname[0]) if(result == FR_OK && info.fname[0])
{ {
initScreens();
u32 *loaderAddress = (u32 *)0x24FFFF00; u32 *loaderAddress = (u32 *)0x24FFFF00;
u8 *payloadAddress = (u8 *)0x24F00000;
memcpy(loaderAddress, loader, loader_size); memcpy(loaderAddress, loader, loader_size);
concatenateStrings(path, "/"); concatenateStrings(path, "/");
concatenateStrings(path, info.altname); concatenateStrings(path, info.altname);
loaderAddress[1] = fileRead((void *)0x24F00000, path); u32 payloadSize = fileRead(payloadAddress, path, (u8 *)loaderAddress - payloadAddress);
if(payloadSize > 0)
{
loaderAddress[1] = payloadSize;
initScreens();
flushDCacheRange(loaderAddress, loader_size); flushDCacheRange(loaderAddress, loader_size);
flushICacheRange(loaderAddress, loader_size); flushICacheRange(loaderAddress, loader_size);
@ -142,6 +146,7 @@ void loadPayload(u32 pressed)
((void (*)())loaderAddress)(); ((void (*)())loaderAddress)();
} }
} }
}
u32 firmRead(void *dest, u32 firmType) u32 firmRead(void *dest, u32 firmType)
{ {
@ -187,7 +192,7 @@ u32 firmRead(void *dest, u32 firmType)
//Convert back the .app name from integer to array //Convert back the .app name from integer to array
hexItoa(firmVersion, &path[35], 8); hexItoa(firmVersion, &path[35], 8);
fileRead(dest, path); fileRead(dest, path, 0);
return firmVersion; return firmVersion;
} }

View File

@ -29,7 +29,7 @@
extern bool isN3DS; extern bool isN3DS;
void mountFs(void); void mountFs(void);
u32 fileRead(void *dest, const char *path); u32 fileRead(void *dest, const char *path, u32 maxSize);
u32 getFileSize(const char *path); u32 getFileSize(const char *path);
bool fileWrite(const void *buffer, const char *path, u32 size); bool fileWrite(const void *buffer, const char *path, u32 size);
void fileDelete(const char *path); void fileDelete(const char *path);

View File

@ -108,7 +108,7 @@ bool verifyPin(void)
{ {
PinData pin; PinData pin;
if(fileRead(&pin, PIN_PATH) != sizeof(PinData) || if(fileRead(&pin, PIN_PATH, sizeof(PinData)) != sizeof(PinData) ||
memcmp(pin.magic, "PINF", 4) != 0 || memcmp(pin.magic, "PINF", 4) != 0 ||
pin.formatVersionMajor != PIN_VERSIONMAJOR || pin.formatVersionMajor != PIN_VERSIONMAJOR ||
pin.formatVersionMinor != PIN_VERSIONMINOR || pin.formatVersionMinor != PIN_VERSIONMINOR ||

View File

@ -111,13 +111,13 @@ void clearScreens(void)
//Setting up two simultaneous memory fills using the GPU //Setting up two simultaneous memory fills using the GPU
vu32 *REGs_PSC0 = (vu32 *)0x10400010; vu32 *REGs_PSC0 = (vu32 *)0x10400010;
REGs_PSC0[0] = (u32)fb->top_left >> 3; //Start address 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[2] = 0; //Fill value
REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start
vu32 *REGs_PSC1 = (vu32 *)0x10400020; vu32 *REGs_PSC1 = (vu32 *)0x10400020;
REGs_PSC1[0] = (u32)fb->bottom >> 3; //Start address 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[2] = 0; //Fill value
REGs_PSC1[3] = (2 << 8) | 1; //32-bit pattern; start REGs_PSC1[3] = (2 << 8) | 1; //32-bit pattern; start
@ -126,7 +126,7 @@ void clearScreens(void)
if(fb->top_right != fb->top_left) if(fb->top_right != fb->top_left)
{ {
REGs_PSC0[0] = (u32)fb->top_right >> 3; //Start address 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[2] = 0; //Fill value
REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start REGs_PSC0[3] = (2 << 8) | 1; //32-bit pattern; start

View File

@ -23,7 +23,7 @@
#include "strings.h" #include "strings.h"
#include "memory.h" #include "memory.h"
int strlen(const char *string) u32 strlen(const char *string)
{ {
char *stringEnd = (char *)string; char *stringEnd = (char *)string;
@ -40,16 +40,16 @@ void concatenateStrings(char *destination, const char *source)
memcpy(&destination[j], source, i + 1); 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"; const char hexDigits[] = "0123456789ABCDEF";
u32 i = 0; u32 i = 0;
while(number > 0) while(number > 0)
{ {
out[nbDigits - 1 - i++] = hexDigits[number & 0xF]; out[digits - 1 - i++] = hexDigits[number & 0xF];
number >>= 4; number >>= 4;
} }
for(; i < nbDigits; i++) out[nbDigits - 1 - i] = '0'; for(; i < digits; i++) out[digits - 1 - i] = '0';
} }

View File

@ -24,6 +24,6 @@
#include "types.h" #include "types.h"
int strlen(const char *string); u32 strlen(const char *string);
void concatenateStrings(char *destination, const char *source); void concatenateStrings(char *destination, const char *source);
void hexItoa(u32 number, char *out, u32 nbDigits); void hexItoa(u32 number, char *out, u32 digits);

View File

@ -116,7 +116,7 @@ void error(const char *message)
initScreens(); initScreens();
drawString("An error has occurred:", 10, 10, COLOR_RED); 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); drawString("Press any button to shutdown", 10, posY + 2 * SPACING_Y, COLOR_WHITE);
waitInput(); waitInput();