Added Sys_PathType, which reports whether a path is absolute, relative

below, or relative above (uses .. to ascend the filesystem). Changed
file functions in GIB to use this.  GIB can now be initialized in a
non-sandboxed mode, which at the moment means that GIB scripts run with
carne can access the entire filesystem.
This commit is contained in:
Brian Koropoff 2002-11-14 05:28:54 +00:00
parent 7b0c24a386
commit 625e1e36d6
10 changed files with 88 additions and 53 deletions

View file

@ -51,4 +51,4 @@ void GIB_Arg_Strip_Delim (unsigned int arg);
void GIB_Return (const char *str);
void GIB_Builtin_Add (const char *name, void (*func) (void), enum gib_builtin_type_e type);
gib_builtin_t *GIB_Builtin_Find (const char *name);
void GIB_Builtin_Init (void);
void GIB_Builtin_Init (qboolean sandbox);

View file

@ -29,4 +29,4 @@
$Id$
*/
void GIB_Init (void);
void GIB_Init (qboolean sandbox);

View file

@ -44,8 +44,15 @@ extern struct cvar_s *developer;
extern const char sys_char_map[256];
enum e_pathtype {
PATHTYPE_ABSOLUTE,
PATHTYPE_RELATIVE_ABOVE,
PATHTYPE_RELATIVE_BELOW
};
int Sys_FileTime (const char *path);
void Sys_mkdir (const char *path);
enum e_pathtype Sys_PathType (const char *path);
typedef void (*sys_printf_t) (const char *fmt, va_list args);

View file

@ -522,6 +522,23 @@ GIB_Thread_Kill_f (void)
/* File access */
int (*GIB_File_Transform_Path) (dstring_t *path) = NULL;
int
GIB_File_Transform_Path_Null (dstring_t *path)
{
return 0;
}
int
GIB_File_Transform_Path_Secure (dstring_t *path)
{
if (Sys_PathType (path->str) != PATHTYPE_RELATIVE_BELOW)
return -1;
dstring_insertstr (path, 0, com_gamedir);
return 0;
}
void
GIB_File_Read_f (void)
{
@ -534,27 +551,26 @@ GIB_File_Read_f (void)
"usage: file::read path_and_filename");
return;
}
path = COM_CompressPath (GIB_Argv (1));
if (!path[0]) {
if (!*GIB_Argv (1)) {
Cbuf_Error ("file",
"file::read: null filename provided");
return;
}
if (path[0] == '/' || (path[0] == '.' && path[1] == '.')) {
if (GIB_File_Transform_Path (GIB_Argd(1))) {
Cbuf_Error ("access",
"file::read: access to %s denied", path);
"file::read: access to %s denied", GIB_Argv(1));
return;
}
path = GIB_Argv (1);
mark = Hunk_LowMark ();
contents = (char *) COM_LoadHunkFile (path);
if (!contents) {
Cbuf_Error ("file",
"file::read: could not open %s/%s for reading: %s", com_gamedir, path, strerror (errno));
"file::read: could not open %s for reading: %s", path, strerror (errno));
return;
}
GIB_Return (contents);
Hunk_FreeToLowMark (mark);
free (path);
}
void
@ -569,25 +585,24 @@ GIB_File_Write_f (void)
"usage: file::write path_and_filename data");
return;
}
path = COM_CompressPath (GIB_Argv (1));
if (!path[0]) {
if (!*GIB_Argv(1)) {
Cbuf_Error ("file",
"file::write: null filename provided");
return;
}
if (path[0] == '/' || (path[0] == '.' && path[1] == '.')) {
if (GIB_File_Transform_Path (GIB_Argd(1))) {
Cbuf_Error ("access",
"file::write: access to %s denied", path);
"file::write: access to %s denied", GIB_Argv(1));
return;
}
if (!(file = Qopen (va ("%s/%s", com_gamedir, path), "w"))) {
path = GIB_Argv(1);
if (!(file = Qopen (path, "w"))) {
Cbuf_Error ("file",
"file::write: could not open %s/%s for writing: %s", com_gamedir, path, strerror (errno));
"file::write: could not open %s for writing: %s", path, strerror (errno));
return;
}
Qprintf (file, "%s", GIB_Argv (2));
Qclose (file);
free (path);
}
void
@ -605,23 +620,23 @@ GIB_File_Find_f (void)
"usage: file::find glob [path]");
return;
}
path = COM_CompressPath (GIB_Argv (2));
if (GIB_Argc () == 3) {
if (!path[0]) {
if (!*GIB_Argv(2)) {
Cbuf_Error ("file",
"file::find: null path provided");
return;
}
if (path[0] == '/' || (path[0] == '.' && path[1] == '.')) {
if (GIB_File_Transform_Path (GIB_Argd(2))) {
Cbuf_Error ("access",
"file::find: access to %s denied", path);
"file::find: access to %s denied", GIB_Argv(2));
return;
}
}
directory = opendir (va ("%s/%s", com_gamedir, path));
path = GIB_Argv(2);
directory = opendir (path);
if (!directory) {
Cbuf_Error ("file",
"file.find: could not open directory %s/%s: %s", com_gamedir, path, strerror (errno));
"file.find: could not open directory %s: %s", path, strerror (errno));
return;
}
list = dstring_newstr ();
@ -640,14 +655,12 @@ GIB_File_Find_f (void)
else
GIB_Return ("");
dstring_delete (list);
free (path);
}
void
GIB_File_Move_f (void)
{
char *path1, *path2;
dstring_t *from, *to;
if (GIB_Argc () != 3) {
Cbuf_Error ("syntax",
@ -655,30 +668,22 @@ GIB_File_Move_f (void)
"usage: file::move from_file to_file");
return;
}
path1 = COM_CompressPath (GIB_Argv (1));
path2 = COM_CompressPath (GIB_Argv (2));
if (path1[0] == '/' || (path1[0] == '.' && path1[1] == '.')) {
if (GIB_File_Transform_Path (GIB_Argd(1))) {
Cbuf_Error ("access",
"file::move: access to %s denied", path1);
"file::move: access to %s denied", GIB_Argv(1));
return;
}
if (path2[0] == '/' || (path2[0] == '.' && path2[1] == '.')) {
if (GIB_File_Transform_Path (GIB_Argd(2))) {
Cbuf_Error ("access",
"file::move: access to %s denied", path2);
"file::move: access to %s denied", GIB_Argv(2));
return;
}
from = dstring_newstr ();
to = dstring_newstr ();
dsprintf (from, "%s/%s", com_gamedir, path1);
dsprintf (to, "%s/%s", com_gamedir, path2);
if (Qrename (from->str, to->str))
path1 = GIB_Argv(1);
path2 = GIB_Argv(2);
if (Qrename (path1, path2))
Cbuf_Error ("file",
"file::move: could not move %s to %s: %s",
from->str, to->str, strerror(errno));
dstring_delete (from);
dstring_delete (to);
free (path1);
free (path2);
path1, path2, strerror(errno));
}
void
@ -692,17 +697,16 @@ GIB_File_Delete_f (void)
"usage: file::delete file");
return;
}
path = COM_CompressPath (GIB_Argv (1));
if (path[0] == '/' || (path[0] == '.' && path[1] == '.')) {
if (GIB_File_Transform_Path (GIB_Argd(1))) {
Cbuf_Error ("access",
"file::delete: access to %s denied", path);
"file::delete: access to %s denied", GIB_Argv(1));
return;
}
if (Qremove(va("%s/%s", com_gamedir, path)))
path = GIB_Argv (1);
if (Qremove(path))
Cbuf_Error ("file",
"file::delete: could not delete %s/%s: %s",
com_gamedir, path, strerror(errno));
free (path);
"file::delete: could not delete %s: %s",
path, strerror(errno));
}
void
@ -750,10 +754,15 @@ GIB_Print_f (void)
}
void
GIB_Builtin_Init (void)
GIB_Builtin_Init (qboolean sandbox)
{
gib_globals = Hash_NewTable (512, GIB_Var_Get_Key, GIB_Var_Free, 0);
if (sandbox)
GIB_File_Transform_Path = GIB_File_Transform_Path_Secure;
else
GIB_File_Transform_Path = GIB_File_Transform_Path_Null;
GIB_Builtin_Add ("function", GIB_Function_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("function::get", GIB_Function_Get_f, GIB_BUILTIN_NORMAL);
GIB_Builtin_Add ("function::export", GIB_Function_Export_f, GIB_BUILTIN_NORMAL);

View file

@ -76,7 +76,7 @@ GIB_Exec_Override_f (void) {
}
void
GIB_Init (void)
GIB_Init (qboolean sandbox)
{
// Override the exec command with a GIB-aware one
if (Cmd_Exists("exec")) {
@ -84,5 +84,5 @@ GIB_Init (void)
Cmd_AddCommand ("exec", GIB_Exec_Override_f, "Execute a script file.");
}
// Initialize builtins
GIB_Builtin_Init ();
GIB_Builtin_Init (sandbox);
}

View file

@ -67,6 +67,7 @@ static const char rcsid[] =
#include "QF/cvar.h"
#include "QF/dstring.h"
#include "QF/sys.h"
#include "QF/quakefs.h"
#include "compat.h"
@ -180,6 +181,24 @@ Sys_FileTime (const char *path)
return -1;
}
enum e_pathtype
Sys_PathType (const char *path)
{
enum e_pathtype type;
char *comp = COM_CompressPath (path);
if (comp[0] == '/'
#ifdef WIN32
|| (comp[0] && comp[1] == ':')
#endif /* WIN32 */
)
type = PATHTYPE_ABSOLUTE;
else if (comp[0] == '.' && comp[1] == '.')
type = PATHTYPE_RELATIVE_ABOVE;
else
type = PATHTYPE_RELATIVE_BELOW;
free (comp);
return type;
}
/*
Sys_SetPrintf

View file

@ -867,7 +867,7 @@ Host_Init (void)
Sys_Init ();
Cmd_Init ();
GIB_Init ();
GIB_Init (true);
// execute +set as early as possible
Cmd_StuffCmds (host_cbuf);

View file

@ -1671,7 +1671,7 @@ Host_Init (void)
Sys_Init ();
Cmd_Init ();
GIB_Init ();
GIB_Init (true);
// execute +set as early as possible
Cmd_StuffCmds (cl_cbuf);

View file

@ -2470,7 +2470,7 @@ SV_Init (void)
Cvar_Get ("cmd_warncmd", "1", CVAR_NONE, NULL, NULL);
Cmd_Init ();
GIB_Init ();
GIB_Init (true);
// execute +set as early as possible
Cmd_StuffCmds (sv_cbuf);

View file

@ -31,7 +31,7 @@ int main (int argc, char **argv)
Cvar_Init_Hash ();
Cmd_Init_Hash ();
Cmd_Init ();
GIB_Init ();
GIB_Init (false); // No sandbox
// Load the script
file = Qopen (argv[1], "r");