Browse Source

[lua] prevent tampering with global "lighty" table

Change-Id: If92ea8d7b58868904ab6d1ffaa27534cb09b7d29
personal/stbuehler/freebsd-3071
Stefan Bühler 2 months ago
parent
commit
53337c81d4
  1. 13
      include/lighttpd/core_lua.h
  2. 23
      src/main/core_lua.c
  3. 2
      src/modules/mod_memcached.c

13
include/lighttpd/core_lua.h

@ -14,6 +14,9 @@ LI_API liLuaState *li_lua_state_get(lua_State *L);
INLINE void li_lua_lock(liLuaState *LL);
INLINE void li_lua_unlock(liLuaState *LL);
/* expect (meta)table at top of the stack */
INLINE void li_lua_protect_metatable(lua_State *L);
/* chunk_lua.c */
LI_API void li_lua_init_chunk_mt(lua_State *L);
@ -30,9 +33,11 @@ LI_API int li_lua_push_environment(lua_State *L, liEnvironment *env);
/* filters_lua.c */
LI_API void li_lua_init_filter_mt(lua_State *L);
/* create entries in `lighty.` table, which must be on top of the stack */
LI_API void li_lua_init_filters(lua_State *L, liServer* srv);
LI_API liFilter* li_lua_get_filter(lua_State *L, int ndx);
LI_API int li_lua_push_filter(lua_State *L, liFilter *f);
LI_API void li_lua_init_filters(lua_State *L, liServer* srv);
LI_API liFilter* li_lua_vrequest_add_filter_in(lua_State *L, liVRequest *vr, int state_ndx);
LI_API liFilter* li_lua_vrequest_add_filter_out(lua_State *L, liVRequest *vr, int state_ndx);
@ -135,4 +140,10 @@ INLINE void li_lua_unlock(liLuaState *LL) {
g_static_rec_mutex_unlock(&LL->lualock);
}
INLINE void li_lua_protect_metatable(lua_State *L) {
/* __metatable key prevents accessing metatable of objects/tables in normal lua code */
lua_pushboolean(L, FALSE);
lua_setfield(L, -2, "__metatable");
}
#endif

23
src/main/core_lua.c

@ -318,7 +318,7 @@ static int li_lua_kvl_to_table(lua_State *L) {
}
#endif
static void lua_push_constants(lua_State *L, int ndx) {
static void li_lua_push_lighty_constants(lua_State *L, int ndx) {
lua_pushinteger(L, LI_HANDLER_GO_ON);
lua_setfield(L, ndx, "HANDLER_GO_ON");
lua_pushinteger(L, LI_HANDLER_COMEBACK);
@ -358,9 +358,16 @@ void li_lua_init2(liLuaState *LL, liServer *srv, liWorker *wrk) {
lua_setfield(L, LUA_REGISTRYINDEX, LI_LUA_REGISTRY_WORKER);
}
lua_newtable(L); /* lighty. */
/* create read-only lighty "table" (zero-sized userdata object) */
lua_newuserdata(L, 0); /* lighty. */
lua_newtable(L); /* metatable(lighty) */
/* prevent tampering with the metatable */
li_lua_protect_metatable(L);
lua_newtable(L); /* metatable(lighty).__index */
/* create lighty.filter_in and lighty.filter_out: */
li_lua_init_filters(L, srv);
/* lighty.print (and lighty.error and global print) */
lua_pushlightuserdata(L, srv);
lua_pushlightuserdata(L, wrk);
lua_pushcclosure(L, li_lua_error, 2);
@ -370,21 +377,25 @@ void li_lua_init2(liLuaState *LL, liServer *srv, liWorker *wrk) {
lua_setfield(L, -3, "error");
lua_setfield(L, -2, "print");
/* lighty.warning */
lua_pushlightuserdata(L, srv);
lua_pushlightuserdata(L, wrk);
lua_pushcclosure(L, li_lua_warning, 2);
lua_setfield(L, -2, "warning");
/* lighty.info */
lua_pushlightuserdata(L, srv);
lua_pushlightuserdata(L, wrk);
lua_pushcclosure(L, li_lua_info, 2);
lua_setfield(L, -2, "info");
/* lighty.debug */
lua_pushlightuserdata(L, srv);
lua_pushlightuserdata(L, wrk);
lua_pushcclosure(L, li_lua_debug, 2);
lua_setfield(L, -2, "debug");
/* lighty.{md5,sha1,sha256} */
lua_pushcclosure(L, li_lua_md5, 0);
lua_setfield(L, -2, "md5");
lua_pushcclosure(L, li_lua_sha1, 0);
@ -392,11 +403,17 @@ void li_lua_init2(liLuaState *LL, liServer *srv, liWorker *wrk) {
lua_pushcclosure(L, li_lua_sha256, 0);
lua_setfield(L, -2, "sha256");
/* lighty.path_simplify */
lua_pushcclosure(L, li_lua_path_simplify, 0);
lua_setfield(L, -2, "path_simplify");
lua_push_constants(L, -2);
li_lua_push_lighty_constants(L, -2);
/* set __index for metatable(lighty) */
lua_setfield(L, -2, "__index");
/* associate metatable(lighty) */
lua_setmetatable(L, -2);
/* store "lighty" object in globals */
lua_setfield(L, LUA_GLOBALSINDEX, "lighty");
li_lua_store_globals(L);

2
src/modules/mod_memcached.c

@ -1127,8 +1127,10 @@ static void mod_memcached_lua_init(liLuaState *LL, liServer *srv, liWorker *wrk,
if (wrk) {
li_lua_lock(LL);
/* memcached global table */
lua_newtable(L); /* { } */
/* memcached.new */
lua_pushlightuserdata(L, wrk);
lua_pushcclosure(L, mc_lua_new, 1);
lua_setfield(L, -2, "new");

Loading…
Cancel
Save