Lua sandbox
This is enough to prevent abuse by denying access to functions and
denial of service (RAM and instruction step limits), but not enough
to allow restricted use of things that require finer control (e.g.
filesystem access).
If something goes wrong, the whole thing can be turned off, for
now, in config.h (see NHL_SANDBOX).
None of the current functionality requires changes to build systems;
some of the possible future functionality may require some #defines
- TBD. There is lots of dead code (#ifdef notyet) for bits of that
additional functionality; we can rip it out if we don't want those
additions or we can complete (parts of) it depending on our needs.
All current uses of Lua are connected to sandboxes and guarded with
nhl_pcall (sandbox and lua_pcall wrapper); options and limits can
be set at the callsites in the passed nhl_sandbox_info. Some of
the error handling may be wrong - panic() vs. impossible() vs
silence.
Memory and instruction step limits should be tuned prior to release;
there's no point tuning them now.
This commit is contained in:
@@ -640,6 +640,10 @@ typedef unsigned char uchar;
|
||||
|
||||
#define USE_ISAAC64 /* Use cross-plattform, bundled RNG */
|
||||
|
||||
/* TEMPORARY - MAKE UNCONDITIONAL BEFORE RELEASE */
|
||||
/* undef this to check if sandbox breaks something */
|
||||
#define NHL_SANDBOX
|
||||
|
||||
/* End of Section 4 */
|
||||
|
||||
#ifdef TTY_TILES_ESCCODES
|
||||
|
||||
@@ -1773,10 +1773,11 @@ extern int l_obj_register(lua_State *);
|
||||
extern void l_nhcore_init(void);
|
||||
extern void l_nhcore_done(void);
|
||||
extern void l_nhcore_call(int);
|
||||
extern lua_State * nhl_init(void);
|
||||
extern lua_State * nhl_init(nhl_sandbox_info *);
|
||||
extern void nhl_done(lua_State *);
|
||||
extern boolean nhl_loadlua(lua_State *, const char *);
|
||||
extern boolean load_lua(const char *);
|
||||
extern int nhl_pcall(lua_State *, int, int);
|
||||
extern boolean load_lua(const char *, nhl_sandbox_info *);
|
||||
extern void nhl_error(lua_State *, const char *) NORETURN;
|
||||
extern void lcheck_param_table(lua_State *);
|
||||
extern schar get_table_mapchr(lua_State *, const char *);
|
||||
@@ -1802,6 +1803,7 @@ extern int get_table_option(lua_State *, const char *, const char *,
|
||||
extern int str_lines_max_width(const char *);
|
||||
extern char *stripdigits(char *);
|
||||
extern const char *get_lua_version(void);
|
||||
extern void nhl_pushhooked_open_table(lua_State *L);
|
||||
#endif /* !CROSSCOMPILE || CROSSCOMPILE_TARGET */
|
||||
|
||||
/* ### nhregex.c ### */
|
||||
|
||||
@@ -493,4 +493,65 @@ extern struct nomakedefs_s nomakedefs;
|
||||
#define LL_DUMP 0x4000L /* none of the above but should be in dumplog */
|
||||
#define LL_DEBUG 0x8000L /* For debugging messages and other spam */
|
||||
|
||||
/*
|
||||
* Lua sandbox
|
||||
*/
|
||||
/* Control block for setting up a Lua state with nhl_init(). */
|
||||
typedef struct nhl_sandbox_info {
|
||||
uint32_t flags; /* see below */
|
||||
uint32_t memlimit; /* approximate memory limit */
|
||||
uint32_t steps; /* instruction limit for state OR ... */
|
||||
uint32_t perpcall; /* ... instruction limit per nhl_pcall */
|
||||
} nhl_sandbox_info;
|
||||
|
||||
/* For efficiency, we only check every NHL_SB_STEPSIZE instructions. */
|
||||
#ifndef NHL_SB_STEPSIZE
|
||||
#define NHL_SB_STEPSIZE 1000
|
||||
#endif
|
||||
|
||||
/* High level groups. Use these flags. */
|
||||
/* Safe functions. */
|
||||
#define NHL_SB_SAFE 0x80000000
|
||||
/* Access to Lua version information. */
|
||||
#define NHL_SB_VERSION 0x40000000
|
||||
#ifdef notyet
|
||||
/* XXX These need to be replaced. */
|
||||
#define NHL_SB_CANREAD 0x20000000
|
||||
#define NHL_SB_CANWRITE 0x10000000
|
||||
#endif
|
||||
/* Debugging library - highly unsafe. */
|
||||
#define NHL_SB_DEBUGGING 0x08000000
|
||||
/* Use with memlimit/steps/perpcall to get usage. */
|
||||
#define NHL_SB_REPORT 0x04000000
|
||||
/* As above, but do full gc on each nhl_pcall. */
|
||||
#define NHL_SB_REPORT2 0x02000000
|
||||
|
||||
/* Low level groups. If you need these, you probably need to define
|
||||
* a new high level group instead. */
|
||||
#define NHL_SB_DB 0x00000001
|
||||
#define NHL_SB_STRING 0x00000002
|
||||
#define NHL_SB_TABLE 0x00000004
|
||||
#define NHL_SB_COROUTINE 0x00000008
|
||||
#define NHL_SB_MATH 0x00000010
|
||||
#define NHL_SB_UTF8 0x00000020
|
||||
#ifdef notyet
|
||||
#define NHL_SB_PACKAGE 0x00000040
|
||||
#define NHL_SB_IO 0x00000080
|
||||
#define NHL_SB_OS 0x00000100
|
||||
#endif
|
||||
|
||||
#define NHL_SB_BASEMASK 0x0001f000
|
||||
#define NHL_SB_BASE_BASE 0x00001000
|
||||
#define NHL_SB_BASE_ERROR 0x00002000
|
||||
#define NHL_SB_BASE_META 0x00004000
|
||||
#define NHL_SB_BASE_GC 0x00008000
|
||||
#define NHL_SB_BASE_UNSAFE 0x00010000
|
||||
|
||||
#define NHL_SB_ALL 0x0000ffff
|
||||
|
||||
/* return codes */
|
||||
#define NHL_SBRV_DENY 1
|
||||
#define NHL_SBRV_ACCEPT 2
|
||||
#define NHL_SBRV_FAIL 3
|
||||
|
||||
#endif /* GLOBAL_H */
|
||||
|
||||
Reference in New Issue
Block a user