Sandboxed thread stuff
This commit is contained in:
commit
9e025a5109
14
Makefile
Normal file
14
Makefile
Normal file
@ -0,0 +1,14 @@
|
||||
LUA_CFLAGS != pkg-config lua5.1 --cflags
|
||||
LIBTOOL = libtool --tag=CC --silent
|
||||
|
||||
preempter.so: preempter.c
|
||||
$(LIBTOOL) --mode=compile cc $(LUA_CFLAGS) -c preempter.c
|
||||
$(LIBTOOL) --mode=link cc -rpath / $(LUA_CFLAGS) -o libpreempter.la preempter.lo
|
||||
mv .libs/libpreempter.so.0.0.0 preempter.so
|
||||
rm libpreempter.la preempter.lo preempter.o
|
||||
|
||||
clean:
|
||||
rm libpreempter.la preempter.lo preempter.o preempter.so
|
||||
rm -rf .libs
|
||||
|
||||
main: preempter.so
|
72
preempter.c
Normal file
72
preempter.c
Normal file
@ -0,0 +1,72 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
|
||||
lua_Hook old_hook;
|
||||
int old_mask;
|
||||
int old_count;
|
||||
|
||||
void yield_hook(lua_State *L, lua_Debug *ar) {
|
||||
lua_yield(L, 0);
|
||||
}
|
||||
|
||||
void activate_preempt(lua_State *L, int interval) {
|
||||
old_hook = lua_gethook(L);
|
||||
old_mask = lua_gethookmask(L);
|
||||
old_count = lua_gethookcount(L);
|
||||
lua_sethook(L, yield_hook, LUA_MASKCOUNT, interval);
|
||||
}
|
||||
|
||||
void disable_preempt(lua_State *L) {
|
||||
lua_sethook(L, old_hook, old_mask, old_count);
|
||||
}
|
||||
|
||||
// Arguments: instruction count, thread, other arguments
|
||||
// Returns: Whatever the thread yields, or error data
|
||||
int sandboxed_resume(lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TNUMBER);
|
||||
luaL_checktype(L, 2, LUA_TTHREAD);
|
||||
|
||||
int total_args = lua_gettop(L);
|
||||
int resume_args = total_args - 2;
|
||||
int instr_count = lua_tointeger(L, 1);
|
||||
|
||||
// Push args onto the thread stack
|
||||
lua_State *thread_state = lua_tothread(L, 2);
|
||||
lua_xmove(L, thread_state, resume_args);
|
||||
|
||||
// Run with preemption
|
||||
activate_preempt(thread_state, instr_count);
|
||||
int res = lua_resume(thread_state, resume_args);
|
||||
disable_preempt(thread_state);
|
||||
|
||||
// Success
|
||||
if (res == LUA_YIELD || res == 0) {
|
||||
lua_pushboolean(L, 1);
|
||||
int resnum = lua_gettop(thread_state);
|
||||
lua_xmove(thread_state, L, resnum);
|
||||
return 1 + resnum;
|
||||
} else { // Error
|
||||
lua_pushboolean(L, 0);
|
||||
lua_xmove(thread_state, L, 1);
|
||||
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Arguments: global environment, main function
|
||||
int sandboxed_create(lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TTABLE);
|
||||
luaL_checktype(L, 1, LUA_TFUNCTION);
|
||||
|
||||
// Put a new thread at the bottom of the stack
|
||||
lua_State *thread_state = lua_newthread(L);
|
||||
lua_insert(L, 1);
|
||||
|
||||
// Set the function of the thread
|
||||
lua_xmove(L, thread_state, 1);
|
||||
|
||||
lua_setfenv(L, 1);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user