Add -unsafefopen commandline argument to allow disabling the qc fopen sandboxing (like the original frik_file spec).
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6316 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
2383c618ee
commit
9c47966653
1 changed files with 43 additions and 11 deletions
|
@ -2495,11 +2495,35 @@ typedef struct {
|
||||||
} pf_fopen_files_t;
|
} pf_fopen_files_t;
|
||||||
static pf_fopen_files_t pf_fopen_files[MAX_QC_FILES];
|
static pf_fopen_files_t pf_fopen_files[MAX_QC_FILES];
|
||||||
|
|
||||||
|
static qboolean QC_PathRequiresSandbox(const char *name)
|
||||||
|
{
|
||||||
|
//if its a user config, ban any fallback locations so that csqc can't read passwords or whatever.
|
||||||
|
/* (sorry about the windows paths, it avoids compiler warnings... -Werror sucks)
|
||||||
|
bad:
|
||||||
|
*.cfg
|
||||||
|
configs\*.cfg
|
||||||
|
allowed:
|
||||||
|
particles\*.cfg (required for particle editor type stuff)
|
||||||
|
huds\*.cfg (shouldn't have any passwords. yay editing)
|
||||||
|
models\*.* (xonotic is evil)
|
||||||
|
sound\*.* (xonotic is evil)
|
||||||
|
*/
|
||||||
|
if ((!strchr(name, '/') || !strnicmp(name, "configs/", 8)) //
|
||||||
|
&& !stricmp(COM_GetFileExtension(name, NULL), ".cfg"))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//returns false if the file is denied.
|
//returns false if the file is denied.
|
||||||
//fallbackread can be NULL, if the qc is not allowed to read that (original) file at all.
|
//fallbackread can be NULL, if the qc is not allowed to read that (original) file at all.
|
||||||
qboolean QC_FixFileName(const char *name, const char **result, const char **fallbackread)
|
qboolean QC_FixFileName(const char *name, const char **result, const char **fallbackread)
|
||||||
{
|
{
|
||||||
char ext[8];
|
if (!strncmp(name, "file:", 5))
|
||||||
|
{
|
||||||
|
*result = name;
|
||||||
|
*fallbackread = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!*name || //blank names are bad
|
if (!*name || //blank names are bad
|
||||||
strchr(name, ':') || //dos/win absolute path, ntfs ADS, amiga drives. reject them all.
|
strchr(name, ':') || //dos/win absolute path, ntfs ADS, amiga drives. reject them all.
|
||||||
|
@ -2510,13 +2534,22 @@ qboolean QC_FixFileName(const char *name, const char **result, const char **fall
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
*fallbackread = name;
|
if (!strncmp(name, "data/", 5))
|
||||||
//if its a user config, ban any fallback locations so that csqc can't read passwords or whatever.
|
{
|
||||||
if ((!strchr(name, '/') || strnicmp(name, "configs/", 8))
|
*fallbackread = NULL; //don't be weird.
|
||||||
&& !stricmp(COM_FileExtension(name, ext, sizeof(ext)), "cfg")
|
*result = name; //already has a data/ prefix.
|
||||||
&& strnicmp(name, "particles/", 10) && strnicmp(name, "huds/", 5) && strnicmp(name, "models/", 7))
|
}
|
||||||
*fallbackread = NULL;
|
else if (COM_CheckParm("-unsafefopen") && !QC_PathRequiresSandbox(name))
|
||||||
|
{
|
||||||
|
*fallbackread = va("data/%s", name); //in case the mod was distributed with a data/ subdir.
|
||||||
|
*result = name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*fallbackread = QC_PathRequiresSandbox(name)?NULL:name;
|
||||||
*result = va("data/%s", name);
|
*result = va("data/%s", name);
|
||||||
|
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2741,7 +2774,6 @@ int PR_QCFile_From_Buffer (pubprogfuncs_t *prinst, const char *name, void *buffe
|
||||||
//internal function used by search_begin
|
//internal function used by search_begin
|
||||||
static int PF_fopen_search (pubprogfuncs_t *prinst, const char *name, flocation_t *loc)
|
static int PF_fopen_search (pubprogfuncs_t *prinst, const char *name, flocation_t *loc)
|
||||||
{
|
{
|
||||||
const char *fallbackread;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
Con_DPrintf("qcfopen(\"%s\") called\n", name);
|
Con_DPrintf("qcfopen(\"%s\") called\n", name);
|
||||||
|
@ -2756,7 +2788,7 @@ static int PF_fopen_search (pubprogfuncs_t *prinst, const char *name, flocation_
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!QC_FixFileName(name, &name, &fallbackread) || !fallbackread)
|
if (QC_PathRequiresSandbox(name))
|
||||||
{ //we're ignoring the data/ dir so using only the fallback, but still blocking it if its a nasty path.
|
{ //we're ignoring the data/ dir so using only the fallback, but still blocking it if its a nasty path.
|
||||||
Con_Printf("qcfopen(\"%s\"): Access denied\n", name);
|
Con_Printf("qcfopen(\"%s\"): Access denied\n", name);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -2764,7 +2796,7 @@ static int PF_fopen_search (pubprogfuncs_t *prinst, const char *name, flocation_
|
||||||
|
|
||||||
pf_fopen_files[i].accessmode = FRIK_FILE_READ_DELAY;
|
pf_fopen_files[i].accessmode = FRIK_FILE_READ_DELAY;
|
||||||
|
|
||||||
Q_strncpyz(pf_fopen_files[i].name, fallbackread, sizeof(pf_fopen_files[i].name));
|
Q_strncpyz(pf_fopen_files[i].name, name, sizeof(pf_fopen_files[i].name));
|
||||||
if (loc->search->handle)
|
if (loc->search->handle)
|
||||||
pf_fopen_files[i].file = FS_OpenReadLocation(name, loc);
|
pf_fopen_files[i].file = FS_OpenReadLocation(name, loc);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue