Sandboxed thread stuff

This commit is contained in:
raymoo 2016-11-11 23:47:17 -08:00
commit 9e025a5109
2 changed files with 86 additions and 0 deletions

14
Makefile Normal file
View 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
View 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);
}