suricata
util-lua-sandbox.h
Go to the documentation of this file.
1 /* Copyright (C) 2023-2024 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Jo Johnson <pyrojoe314@gmail.com>
22  */
23 
24 #ifndef SURICATA_UTIL_LUA_SANDBOX_H
25 #define SURICATA_UTIL_LUA_SANDBOX_H
26 
27 #include "lua.h"
28 #include "suricata-common.h"
29 
30 /*
31  * Lua sandbox usage: The only needed changes to use the sandboxed lua state are
32  * to replace calls to lua_newstate and lua_close with SCLuaSbStateNew and SCLuaSbStateClose
33  * Additionally, SCLuaSbLoadRestricted can be used to load a restricted set of packages
34  * that prevent side effecting outside of the lua runtime
35  */
36 
37 /*
38  * Struct to store a lua_state and the additional metadata required to sandbox it
39  */
40 typedef struct SCLuaSbState {
42 
43  /* Allocation limits */
44  size_t alloc_bytes;
45  uint64_t alloc_limit;
46 
47  /* Execution Limits */
50  // used by lua_sethook
52 
53  /* Errors. */
58 
59 /*
60  * Replaces luaL_newstate. Sets an upper bound for allocations and bytecode
61  * instructions for the lua runtime on this state.
62  *
63  * alloclimit - maximium number of bytes lua can allocate before receiving out of memory.
64  * A value of zero will not limit allocations
65  * instructionlimit - maximum number of lua bytecode instructions before an error is thrown
66  * A value of zero will not limit the number of instructions
67  */
68 lua_State *SCLuaSbStateNew(uint64_t alloclimit, uint64_t instructionlimit);
69 
70 /*
71  * Replaces lua_close. Handles freeing the SCLuaSbState
72  */
74 
75 /**
76  * Retreive the SCLuaSbState from a lua_State.
77  */
79 
80 /*
81  * Resets the instruction counter for the sandbox to 0
82  */
84 
85 /*
86  * Replaces luaL_openlibs. Only opens allowed packages for the sandbox and
87  * masks out dangerous functions from the base.
88  */
89 void SCLuaSbLoadLibs(lua_State *L);
90 
91 /* alloc_limit (max-bytes) handling. To give the script the full budget
92  * during it's execution, temporary disable the limit and then restore
93  * it with the existing use as baseline
94  *
95  * ```
96  * // get configured limit and reset active limit to 0
97  * const uint64_t cfg_limit = SCLuaSbResetBytesLimit(tlua->luastate);
98  * // push some data to the state
99  * LuaPushStringBuffer(tlua->luastate, input, (size_t)input_len);
100  * // restore the limit, which may now be lower than `alloc_bytes`.
101  * SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
102  * // update allowance to take `alloc_bytes` as the baseline, so
103  * // effectively: sb->alloc_bytes + sb->alloc_limit
104  * SCLuaSbUpdateBytesLimit(tlua->luastate);
105  *
106  * ... run script, lua_pcall...
107  *
108  * while (lua_gettop(tlua->luastate) > 0) {
109  * lua_pop(tlua->luastate, 1);
110  * }
111  * // restore the original alloc_limit
112  * SCLuaSbRestoreBytesLimit(tlua->luastate, cfg_limit);
113  * ```
114  */
115 
116 /*
117  * Resets the byte limit and returns the existing limit.
118  * Meant to be used to temporarily disable the limit during preparation
119  * time for a script to run. */
120 uint64_t SCLuaSbResetBytesLimit(lua_State *L);
121 
122 /*
123  * Update the alloc_limit to take the pre-script initialization bytes
124  * as the base line.
125  */
127 
128 /*
129  * Set the bytes limit. Meant to be used with the value returned from
130  * `SCLuaSbResetBytesLimit`
131  */
132 void SCLuaSbRestoreBytesLimit(lua_State *L, const uint64_t cfg_limit);
133 
134 #endif /* SURICATA_UTIL_LUA_SANDBOX_H */
SCLuaSbStateClose
void SCLuaSbStateClose(lua_State *sb)
Definition: util-lua-sandbox.c:361
SCLuaSbState::memory_limit_error
bool memory_limit_error
Definition: util-lua-sandbox.h:56
SCLuaSbUpdateBytesLimit
void SCLuaSbUpdateBytesLimit(lua_State *L)
Definition: util-lua-sandbox.c:396
SCLuaSbState
Definition: util-lua-sandbox.h:40
SCLuaSbState::hook_instruction_count
int hook_instruction_count
Definition: util-lua-sandbox.h:51
SCLuaSbState::L
lua_State * L
Definition: util-lua-sandbox.h:41
SCLuaSbLoadLibs
void SCLuaSbLoadLibs(lua_State *L)
Definition: util-lua-sandbox.c:280
SCLuaSbResetBytesLimit
uint64_t SCLuaSbResetBytesLimit(lua_State *L)
Definition: util-lua-sandbox.c:385
SCLuaSbState
struct SCLuaSbState SCLuaSbState
lua_State
struct lua_State lua_State
Definition: suricata-common.h:523
SCLuaSbRestoreBytesLimit
void SCLuaSbRestoreBytesLimit(lua_State *L, const uint64_t cfg_limit)
Definition: util-lua-sandbox.c:404
SCLuaSbResetInstructionCounter
void SCLuaSbResetInstructionCounter(lua_State *sb)
Definition: util-lua-sandbox.c:415
SCLuaSbState::instruction_count
uint64_t instruction_count
Definition: util-lua-sandbox.h:48
SCLuaSbState::blocked_function_error
bool blocked_function_error
Definition: util-lua-sandbox.h:54
suricata-common.h
SCLuaSbState::instruction_limit
uint64_t instruction_limit
Definition: util-lua-sandbox.h:49
SCLuaSbState::alloc_bytes
size_t alloc_bytes
Definition: util-lua-sandbox.h:44
SCLuaSbState::alloc_limit
uint64_t alloc_limit
Definition: util-lua-sandbox.h:45
SCLuaSbState::instruction_count_error
bool instruction_count_error
Definition: util-lua-sandbox.h:55
SCLuaSbGetContext
SCLuaSbState * SCLuaSbGetContext(lua_State *L)
Definition: util-lua-sandbox.c:352
SCLuaSbStateNew
lua_State * SCLuaSbStateNew(uint64_t alloclimit, uint64_t instructionlimit)
Allocate a new Lua sandbox.
Definition: util-lua-sandbox.c:320