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);
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

View File

@ -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 );

View File

@ -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) {

View File

@ -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);