summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-19 13:14:06 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2019-07-19 13:14:06 -0300
commit3c0d3c6fbeea18f257102c62a01b036c7a5c5161 (patch)
tree138a90dc27593aaf4e873ea8aca5b7d887084e1a
parent440a5ee78c8592230780310c9c8d8c2ba1700cb1 (diff)
downloadlua-3c0d3c6fbeea18f257102c62a01b036c7a5c5161.tar.gz
lua-3c0d3c6fbeea18f257102c62a01b036c7a5c5161.tar.bz2
lua-3c0d3c6fbeea18f257102c62a01b036c7a5c5161.zip
Avoid using addresses of static variables as unique keys
The addresses of static variables may be different for different instances of Lua, making these instances incompatible if they use these addresses as unique keys in the registry (or other tables).
-rw-r--r--ldblib.c18
-rw-r--r--loadlib.c11
-rw-r--r--testes/db.lua4
3 files changed, 17 insertions, 16 deletions
diff --git a/ldblib.c b/ldblib.c
index 513a13cb..64158395 100644
--- a/ldblib.c
+++ b/ldblib.c
@@ -21,10 +21,10 @@
21 21
22 22
23/* 23/*
24** The hook table at registry[&HOOKKEY] maps threads to their current 24** The hook table at registry[HOOKKEY] maps threads to their current
25** hook function. (We only need the unique address of 'HOOKKEY'.) 25** hook function.
26*/ 26*/
27static const int HOOKKEY = 0; 27static const char* HOOKKEY = "_HOOKKEY";
28 28
29 29
30/* 30/*
@@ -314,7 +314,7 @@ static int db_upvaluejoin (lua_State *L) {
314static void hookf (lua_State *L, lua_Debug *ar) { 314static void hookf (lua_State *L, lua_Debug *ar) {
315 static const char *const hooknames[] = 315 static const char *const hooknames[] =
316 {"call", "return", "line", "count", "tail call"}; 316 {"call", "return", "line", "count", "tail call"};
317 lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY); 317 lua_getfield(L, LUA_REGISTRYINDEX, HOOKKEY);
318 lua_pushthread(L); 318 lua_pushthread(L);
319 if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */ 319 if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */
320 lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */ 320 lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */
@@ -367,14 +367,12 @@ static int db_sethook (lua_State *L) {
367 count = (int)luaL_optinteger(L, arg + 3, 0); 367 count = (int)luaL_optinteger(L, arg + 3, 0);
368 func = hookf; mask = makemask(smask, count); 368 func = hookf; mask = makemask(smask, count);
369 } 369 }
370 if (lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY) == LUA_TNIL) { 370 if (!luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY)) {
371 lua_createtable(L, 0, 2); /* create a hook table */ 371 /* table just created; initialize it */
372 lua_pushvalue(L, -1);
373 lua_rawsetp(L, LUA_REGISTRYINDEX, &HOOKKEY); /* set it in position */
374 lua_pushstring(L, "k"); 372 lua_pushstring(L, "k");
375 lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ 373 lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */
376 lua_pushvalue(L, -1); 374 lua_pushvalue(L, -1);
377 lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ 375 lua_setmetatable(L, -2); /* metatable(hooktable) = hooktable */
378 } 376 }
379 checkstack(L, L1, 1); 377 checkstack(L, L1, 1);
380 lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */ 378 lua_pushthread(L1); lua_xmove(L1, L, 1); /* key (thread) */
@@ -396,7 +394,7 @@ static int db_gethook (lua_State *L) {
396 else if (hook != hookf) /* external hook? */ 394 else if (hook != hookf) /* external hook? */
397 lua_pushliteral(L, "external hook"); 395 lua_pushliteral(L, "external hook");
398 else { /* hook table must exist */ 396 else { /* hook table must exist */
399 lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY); 397 lua_getfield(L, LUA_REGISTRYINDEX, HOOKKEY);
400 checkstack(L, L1, 1); 398 checkstack(L, L1, 1);
401 lua_pushthread(L1); lua_xmove(L1, L, 1); 399 lua_pushthread(L1); lua_xmove(L1, L, 1);
402 lua_rawget(L, -2); /* 1st result = hooktable[L1] */ 400 lua_rawget(L, -2); /* 1st result = hooktable[L1] */
diff --git a/loadlib.c b/loadlib.c
index b72dd885..9ef00278 100644
--- a/loadlib.c
+++ b/loadlib.c
@@ -56,10 +56,10 @@
56 56
57 57
58/* 58/*
59** unique key for table in the registry that keeps handles 59** key for table in the registry that keeps handles
60** for all loaded C libraries 60** for all loaded C libraries
61*/ 61*/
62static const int CLIBS = 0; 62static const char *CLIBS = "_CLIBS";
63 63
64#define LIB_FAIL "open" 64#define LIB_FAIL "open"
65 65
@@ -327,7 +327,7 @@ static void setpath (lua_State *L, const char *fieldname,
327*/ 327*/
328static void *checkclib (lua_State *L, const char *path) { 328static void *checkclib (lua_State *L, const char *path) {
329 void *plib; 329 void *plib;
330 lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS); 330 lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
331 lua_getfield(L, -1, path); 331 lua_getfield(L, -1, path);
332 plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ 332 plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */
333 lua_pop(L, 2); /* pop CLIBS table and 'plib' */ 333 lua_pop(L, 2); /* pop CLIBS table and 'plib' */
@@ -340,7 +340,7 @@ static void *checkclib (lua_State *L, const char *path) {
340** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries 340** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries
341*/ 341*/
342static void addtoclib (lua_State *L, const char *path, void *plib) { 342static void addtoclib (lua_State *L, const char *path, void *plib) {
343 lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS); 343 lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
344 lua_pushlightuserdata(L, plib); 344 lua_pushlightuserdata(L, plib);
345 lua_pushvalue(L, -1); 345 lua_pushvalue(L, -1);
346 lua_setfield(L, -3, path); /* CLIBS[path] = plib */ 346 lua_setfield(L, -3, path); /* CLIBS[path] = plib */
@@ -716,12 +716,11 @@ static void createsearcherstable (lua_State *L) {
716** setting a finalizer to close all libraries when closing state. 716** setting a finalizer to close all libraries when closing state.
717*/ 717*/
718static void createclibstable (lua_State *L) { 718static void createclibstable (lua_State *L) {
719 lua_newtable(L); /* create CLIBS table */ 719 luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */
720 lua_createtable(L, 0, 1); /* create metatable for CLIBS */ 720 lua_createtable(L, 0, 1); /* create metatable for CLIBS */
721 lua_pushcfunction(L, gctm); 721 lua_pushcfunction(L, gctm);
722 lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ 722 lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
723 lua_setmetatable(L, -2); 723 lua_setmetatable(L, -2);
724 lua_rawsetp(L, LUA_REGISTRYINDEX, &CLIBS); /* set CLIBS table in registry */
725} 724}
726 725
727 726
diff --git a/testes/db.lua b/testes/db.lua
index 3d94f776..a64a1130 100644
--- a/testes/db.lua
+++ b/testes/db.lua
@@ -255,6 +255,10 @@ do -- test hook presence in debug info
255end 255end
256 256
257 257
258-- hook table has weak keys
259assert(getmetatable(debug.getregistry()._HOOKKEY).__mode == 'k')
260
261
258a = {}; L = nil 262a = {}; L = nil
259local glob = 1 263local glob = 1
260local oldglob = glob 264local oldglob = glob