mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-01 22:21:05 +00:00
Disallow adding files with absolute path or traversing upward
(Except as part of srb2home, srb2path or addons_folder -- this lets addons menu work, primarily.) - disallowed when using addfile or addfolder - security check for xcmd receive
This commit is contained in:
parent
373af01092
commit
b1a86b0b34
3 changed files with 94 additions and 22 deletions
71
src/d_main.c
71
src/d_main.c
|
@ -1689,3 +1689,74 @@ const char *D_Home(void)
|
|||
if (usehome) return userhome;
|
||||
else return NULL;
|
||||
}
|
||||
|
||||
static boolean check_top_dir(const char **path, const char *top)
|
||||
{
|
||||
// empty string does NOT match
|
||||
if (!strcmp(top, ""))
|
||||
return false;
|
||||
|
||||
if (!startswith(*path, top))
|
||||
return false;
|
||||
|
||||
*path += strlen(top);
|
||||
|
||||
// if it doesn't already end with a path separator,
|
||||
// check if a separator follows
|
||||
if (!endswith(top, PATHSEP))
|
||||
{
|
||||
if (startswith(*path, PATHSEP))
|
||||
*path += strlen(PATHSEP);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cmp_strlen_desc(const void *a, const void *b)
|
||||
{
|
||||
return ((int)strlen(*(const char*const*)b) - (int)strlen(*(const char*const*)a));
|
||||
}
|
||||
|
||||
boolean D_IsPathAllowed(const char *path)
|
||||
{
|
||||
const char *paths[] = {
|
||||
srb2home,
|
||||
srb2path,
|
||||
cv_addons_folder.string
|
||||
};
|
||||
|
||||
const size_t n_paths = sizeof paths / sizeof *paths;
|
||||
|
||||
size_t i;
|
||||
|
||||
// Sort folder paths by longest to shortest so
|
||||
// overlapping paths work. E.g.:
|
||||
// Path 1: /home/james/.srb2/addons
|
||||
// Path 2: /home/james/.srb2
|
||||
qsort(paths, n_paths, sizeof *paths, cmp_strlen_desc);
|
||||
|
||||
// These paths are allowed to be absolute
|
||||
// path is offset so ".." can be checked only in the
|
||||
// rest of the path
|
||||
for (i = 0; i < n_paths; ++i)
|
||||
{
|
||||
if (check_top_dir(&path, paths[i]))
|
||||
break;
|
||||
}
|
||||
|
||||
// Only if none of the presets matched
|
||||
if (i == n_paths)
|
||||
{
|
||||
// Cannot be an absolute path
|
||||
if (M_IsPathAbsolute(path))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cannot traverse upwards
|
||||
if (strstr(path, ".."))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ void D_ProcessEvents(void);
|
|||
|
||||
const char *D_Home(void);
|
||||
|
||||
boolean D_IsPathAllowed(const char *path);
|
||||
|
||||
//
|
||||
// BASE LEVEL
|
||||
//
|
||||
|
|
|
@ -7860,8 +7860,10 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l
|
|||
// Add a wadfile to the active wad files,
|
||||
// replace sounds, musics, patches, textures, sprites and maps
|
||||
//
|
||||
static boolean P_LoadAddon(UINT16 wadnum, UINT16 numlumps)
|
||||
static boolean P_LoadAddon(UINT16 numlumps)
|
||||
{
|
||||
const UINT16 wadnum = (UINT16)(numwadfiles-1);
|
||||
|
||||
size_t i, j, sreplaces = 0, mreplaces = 0, digmreplaces = 0;
|
||||
char *name;
|
||||
lumpinfo_t *lumpinfo;
|
||||
|
@ -7883,6 +7885,12 @@ static boolean P_LoadAddon(UINT16 wadnum, UINT16 numlumps)
|
|||
// UINT16 flaPos, flaNum = 0;
|
||||
// UINT16 mapPos, mapNum = 0;
|
||||
|
||||
if (numlumps == INT16_MAX)
|
||||
{
|
||||
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(wadfiles[wadnum]->type)
|
||||
{
|
||||
case RET_PK3:
|
||||
|
@ -8051,34 +8059,25 @@ static boolean P_LoadAddon(UINT16 wadnum, UINT16 numlumps)
|
|||
return true;
|
||||
}
|
||||
|
||||
boolean P_AddWadFile(const char *wadfilename)
|
||||
static boolean P_CheckAddonPath(const char *path)
|
||||
{
|
||||
UINT16 numlumps, wadnum;
|
||||
|
||||
// Init file.
|
||||
if ((numlumps = W_InitFile(wadfilename, false, false)) == INT16_MAX)
|
||||
if (!D_IsPathAllowed(path))
|
||||
{
|
||||
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
||||
CONS_Alert(CONS_WARNING, "%s: tried to add file, location is not allowed\n", path);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
wadnum = (UINT16)(numwadfiles-1);
|
||||
|
||||
return P_LoadAddon(wadnum, numlumps);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean P_AddWadFile(const char *wadfilename)
|
||||
{
|
||||
return P_CheckAddonPath(wadfilename) &&
|
||||
P_LoadAddon(W_InitFile(wadfilename, false, false));
|
||||
}
|
||||
|
||||
boolean P_AddFolder(const char *folderpath)
|
||||
{
|
||||
UINT16 numlumps, wadnum;
|
||||
|
||||
// Init file.
|
||||
if ((numlumps = W_InitFolder(folderpath, false, false)) == INT16_MAX)
|
||||
{
|
||||
refreshdirmenu |= REFRESHDIR_NOTLOADED;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
wadnum = (UINT16)(numwadfiles-1);
|
||||
|
||||
return P_LoadAddon(wadnum, numlumps);
|
||||
return P_CheckAddonPath(folderpath) &&
|
||||
P_LoadAddon(W_InitFolder(folderpath, false, false));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue