From 519855de5b87f754fb7d4e64097e7497afd27fa2 Mon Sep 17 00:00:00 2001 From: aspargas2 Date: Wed, 24 Jun 2020 23:49:22 -0400 Subject: [PATCH] fix write permission bypass bug attempting to open a file in a bdri mount for reading only which did not exist but had a valid name would create the file without ever unlocking appropriate write permissions --- arm9/source/filesys/fsutil.c | 2 +- arm9/source/filesys/vff.c | 6 +++--- arm9/source/virtual/virtual.c | 8 +++++--- arm9/source/virtual/virtual.h | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/arm9/source/filesys/fsutil.c b/arm9/source/filesys/fsutil.c index ab73c28..0219985 100644 --- a/arm9/source/filesys/fsutil.c +++ b/arm9/source/filesys/fsutil.c @@ -737,7 +737,7 @@ bool PathCopy(const char* destdir, const char* orig, u32* flags) { u64 osize = FileGetSize(orig); VirtualFile dvfile; if (!osize) return false; - if (!GetVirtualFile(&dvfile, dest)) { + if (!GetVirtualFile(&dvfile, dest, FA_WRITE)) { VirtualDir vdir; if (!GetVirtualDir(&vdir, destdir)) return false; while (true) { // search by size should be a last resort solution diff --git a/arm9/source/filesys/vff.c b/arm9/source/filesys/vff.c index 08ca2d6..724d42d 100644 --- a/arm9/source/filesys/vff.c +++ b/arm9/source/filesys/vff.c @@ -18,7 +18,7 @@ FRESULT fvx_open (FIL* fp, const TCHAR* path, BYTE mode) { #if _VFIL_ENABLED VirtualFile* vfile = VFIL(fp); memset(fp, 0, sizeof(FIL)); - if (GetVirtualFile(vfile, path)) { + if (GetVirtualFile(vfile, path, mode)) { fp->obj.fs = NULL; fp->obj.objsize = vfile->size; fp->fptr = 0; @@ -81,7 +81,7 @@ FRESULT fvx_sync (FIL* fp) { FRESULT fvx_stat (const TCHAR* path, FILINFO* fno) { if (GetVirtualSource(path)) { VirtualFile vfile; - if (!GetVirtualFile(&vfile, path)) return FR_NO_PATH; + if (!GetVirtualFile(&vfile, path, FA_READ)) return FR_NO_PATH; if (fno) { fno->fsize = vfile.size; fno->fdate = (1<<5)|(1<<0); // 1 for month / day @@ -102,7 +102,7 @@ FRESULT fvx_rename (const TCHAR* path_old, const TCHAR* path_new) { FRESULT fvx_unlink (const TCHAR* path) { if (GetVirtualSource(path)) { VirtualFile vfile; - if (!GetVirtualFile(&vfile, path)) return FR_NO_PATH; + if (!GetVirtualFile(&vfile, path, FA_READ)) return FR_NO_PATH; if (DeleteVirtualFile(&vfile) != 0) return FR_DENIED; return FR_OK; } else return fa_unlink( path ); diff --git a/arm9/source/virtual/virtual.c b/arm9/source/virtual/virtual.c index 55e7431..ecfb396 100644 --- a/arm9/source/virtual/virtual.c +++ b/arm9/source/virtual/virtual.c @@ -7,6 +7,7 @@ #include "vcart.h" #include "vvram.h" #include "vdisadiff.h" +#include "ff.h" typedef struct { char drv_letter; @@ -107,7 +108,7 @@ bool OpenVirtualDir(VirtualDir* vdir, VirtualFile* ventry) { return true; } -bool GetVirtualFile(VirtualFile* vfile, const char* path) { +bool GetVirtualFile(VirtualFile* vfile, const char* path, u8 mode) { char lpath[256]; strncpy(lpath, path, 256); lpath[255] = '\0'; @@ -129,7 +130,8 @@ bool GetVirtualFile(VirtualFile* vfile, const char* path) { for (name = strtok(lpath + 3, "/"); name && vdir.flags; name = strtok(NULL, "/")) { if (!(vdir.flags & VFLAG_LV3)) { // standard method while (true) { - if (!ReadVirtualDir(vfile, &vdir)) return ((vdir.flags & VRT_BDRI) && GetNewVBDRIFile(vfile, &vdir, path)); + if (!ReadVirtualDir(vfile, &vdir)) + return ((mode & FA_WRITE) && (vdir.flags & VRT_BDRI) && GetNewVBDRIFile(vfile, &vdir, path)); if ((!(vfile->flags & (VRT_GAME|VRT_VRAM)) && (strncasecmp(name, vfile->name, 32) == 0)) || ((vfile->flags & VRT_GAME) && MatchVGameFilename(name, vfile, 256)) || ((vfile->flags & VRT_VRAM) && MatchVVramFilename(name, vfile))) @@ -148,7 +150,7 @@ bool GetVirtualFile(VirtualFile* vfile, const char* path) { bool GetVirtualDir(VirtualDir* vdir, const char* path) { VirtualFile vfile; - return GetVirtualFile(&vfile, path) && OpenVirtualDir(vdir, &vfile); + return GetVirtualFile(&vfile, path, 0) && OpenVirtualDir(vdir, &vfile); } bool GetVirtualFilename(char* name, const VirtualFile* vfile, u32 n_chars) { diff --git a/arm9/source/virtual/virtual.h b/arm9/source/virtual/virtual.h index 4c0f135..7644b4c 100644 --- a/arm9/source/virtual/virtual.h +++ b/arm9/source/virtual/virtual.h @@ -57,7 +57,7 @@ bool ReadVirtualDir(VirtualFile* vfile, VirtualDir* vdir); bool OpenVirtualRoot(VirtualDir* vdir, u32 virtual_src); bool OpenVirtualDir(VirtualDir* vdir, VirtualFile* ventry); -bool GetVirtualFile(VirtualFile* vfile, const char* path); +bool GetVirtualFile(VirtualFile* vfile, const char* path, u8 mode); bool GetVirtualDir(VirtualDir* vdir, const char* path); bool GetVirtualFilename(char* name, const VirtualFile* vfile, u32 n_chars);