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
This commit is contained in:
aspargas2 2020-06-24 23:49:22 -04:00 committed by d0k3
parent 6b6fe4741d
commit 519855de5b
4 changed files with 10 additions and 8 deletions

View File

@ -737,7 +737,7 @@ bool PathCopy(const char* destdir, const char* orig, u32* flags) {
u64 osize = FileGetSize(orig); u64 osize = FileGetSize(orig);
VirtualFile dvfile; VirtualFile dvfile;
if (!osize) return false; if (!osize) return false;
if (!GetVirtualFile(&dvfile, dest)) { if (!GetVirtualFile(&dvfile, dest, FA_WRITE)) {
VirtualDir vdir; VirtualDir vdir;
if (!GetVirtualDir(&vdir, destdir)) return false; if (!GetVirtualDir(&vdir, destdir)) return false;
while (true) { // search by size should be a last resort solution while (true) { // search by size should be a last resort solution

View File

@ -18,7 +18,7 @@ FRESULT fvx_open (FIL* fp, const TCHAR* path, BYTE mode) {
#if _VFIL_ENABLED #if _VFIL_ENABLED
VirtualFile* vfile = VFIL(fp); VirtualFile* vfile = VFIL(fp);
memset(fp, 0, sizeof(FIL)); memset(fp, 0, sizeof(FIL));
if (GetVirtualFile(vfile, path)) { if (GetVirtualFile(vfile, path, mode)) {
fp->obj.fs = NULL; fp->obj.fs = NULL;
fp->obj.objsize = vfile->size; fp->obj.objsize = vfile->size;
fp->fptr = 0; fp->fptr = 0;
@ -81,7 +81,7 @@ FRESULT fvx_sync (FIL* fp) {
FRESULT fvx_stat (const TCHAR* path, FILINFO* fno) { FRESULT fvx_stat (const TCHAR* path, FILINFO* fno) {
if (GetVirtualSource(path)) { if (GetVirtualSource(path)) {
VirtualFile vfile; VirtualFile vfile;
if (!GetVirtualFile(&vfile, path)) return FR_NO_PATH; if (!GetVirtualFile(&vfile, path, FA_READ)) return FR_NO_PATH;
if (fno) { if (fno) {
fno->fsize = vfile.size; fno->fsize = vfile.size;
fno->fdate = (1<<5)|(1<<0); // 1 for month / day 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) { FRESULT fvx_unlink (const TCHAR* path) {
if (GetVirtualSource(path)) { if (GetVirtualSource(path)) {
VirtualFile vfile; 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; if (DeleteVirtualFile(&vfile) != 0) return FR_DENIED;
return FR_OK; return FR_OK;
} else return fa_unlink( path ); } else return fa_unlink( path );

View File

@ -7,6 +7,7 @@
#include "vcart.h" #include "vcart.h"
#include "vvram.h" #include "vvram.h"
#include "vdisadiff.h" #include "vdisadiff.h"
#include "ff.h"
typedef struct { typedef struct {
char drv_letter; char drv_letter;
@ -107,7 +108,7 @@ bool OpenVirtualDir(VirtualDir* vdir, VirtualFile* ventry) {
return true; return true;
} }
bool GetVirtualFile(VirtualFile* vfile, const char* path) { bool GetVirtualFile(VirtualFile* vfile, const char* path, u8 mode) {
char lpath[256]; char lpath[256];
strncpy(lpath, path, 256); strncpy(lpath, path, 256);
lpath[255] = '\0'; 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, "/")) { for (name = strtok(lpath + 3, "/"); name && vdir.flags; name = strtok(NULL, "/")) {
if (!(vdir.flags & VFLAG_LV3)) { // standard method if (!(vdir.flags & VFLAG_LV3)) { // standard method
while (true) { 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)) || if ((!(vfile->flags & (VRT_GAME|VRT_VRAM)) && (strncasecmp(name, vfile->name, 32) == 0)) ||
((vfile->flags & VRT_GAME) && MatchVGameFilename(name, vfile, 256)) || ((vfile->flags & VRT_GAME) && MatchVGameFilename(name, vfile, 256)) ||
((vfile->flags & VRT_VRAM) && MatchVVramFilename(name, vfile))) ((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) { bool GetVirtualDir(VirtualDir* vdir, const char* path) {
VirtualFile vfile; 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) { bool GetVirtualFilename(char* name, const VirtualFile* vfile, u32 n_chars) {

View File

@ -57,7 +57,7 @@ bool ReadVirtualDir(VirtualFile* vfile, VirtualDir* vdir);
bool OpenVirtualRoot(VirtualDir* vdir, u32 virtual_src); bool OpenVirtualRoot(VirtualDir* vdir, u32 virtual_src);
bool OpenVirtualDir(VirtualDir* vdir, VirtualFile* ventry); 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 GetVirtualDir(VirtualDir* vdir, const char* path);
bool GetVirtualFilename(char* name, const VirtualFile* vfile, u32 n_chars); bool GetVirtualFilename(char* name, const VirtualFile* vfile, u32 n_chars);