diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-02-01 19:57:15 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2012-02-01 19:57:15 -0200 |
commit | 678c1255c92eed9c2c7564d340a5563b17395158 (patch) | |
tree | ca35d119d770835b59d34cdec93805190d3155d1 | |
parent | a4b96ce9a3305ae3585c0bb143fa7342c140f20b (diff) | |
download | lua-678c1255c92eed9c2c7564d340a5563b17395158.tar.gz lua-678c1255c92eed9c2c7564d340a5563b17395158.tar.bz2 lua-678c1255c92eed9c2c7564d340a5563b17395158.zip |
random seed used in the hash of all strings to avoid intentional
collisions
-rw-r--r-- | lstate.c | 37 | ||||
-rw-r--r-- | lstate.h | 3 | ||||
-rw-r--r-- | lstring.c | 13 | ||||
-rw-r--r-- | lstring.h | 4 | ||||
-rw-r--r-- | ltable.c | 4 |
5 files changed, 49 insertions, 12 deletions
@@ -1,11 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 2.91 2011/08/23 17:24:34 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.92 2011/10/03 17:54:25 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
6 | 6 | ||
7 | 7 | ||
8 | #include <stddef.h> | 8 | #include <stddef.h> |
9 | #include <string.h> | ||
9 | 10 | ||
10 | #define lstate_c | 11 | #define lstate_c |
11 | #define LUA_CORE | 12 | #define LUA_CORE |
@@ -42,6 +43,17 @@ | |||
42 | 43 | ||
43 | 44 | ||
44 | /* | 45 | /* |
46 | ** a macro to help the creation of a unique random seed when a state is | ||
47 | ** created; the seed is used to randomize hashes. | ||
48 | */ | ||
49 | #if !defined(luai_makeseed) | ||
50 | #include <time.h> | ||
51 | #define luai_makeseed(L) cast(size_t, time(NULL)) | ||
52 | #endif | ||
53 | |||
54 | |||
55 | |||
56 | /* | ||
45 | ** thread state + extra space | 57 | ** thread state + extra space |
46 | */ | 58 | */ |
47 | typedef struct LX { | 59 | typedef struct LX { |
@@ -66,6 +78,28 @@ typedef struct LG { | |||
66 | 78 | ||
67 | 79 | ||
68 | /* | 80 | /* |
81 | ** Compute an initial seed as random as possible. In ANSI, rely on | ||
82 | ** Address Space Layour Randomization (if present) to increase | ||
83 | ** randomness.. | ||
84 | */ | ||
85 | #define addbuff(b,p,e) \ | ||
86 | { size_t t = cast(size_t, e); \ | ||
87 | memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); } | ||
88 | |||
89 | static unsigned int makeseed (lua_State *L) { | ||
90 | char buff[4 * sizeof(size_t)]; | ||
91 | unsigned int h = luai_makeseed(); | ||
92 | int p = 0; | ||
93 | addbuff(buff, p, L); /* heap variable */ | ||
94 | addbuff(buff, p, &h); /* local variable */ | ||
95 | addbuff(buff, p, luaO_nilobject); /* global variable */ | ||
96 | addbuff(buff, p, &lua_newstate); /* public function */ | ||
97 | lua_assert(p == sizeof(buff)); | ||
98 | return luaS_hash(buff, p, h); | ||
99 | } | ||
100 | |||
101 | |||
102 | /* | ||
69 | ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) | 103 | ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) |
70 | ** invariant | 104 | ** invariant |
71 | */ | 105 | */ |
@@ -242,6 +276,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
242 | g->frealloc = f; | 276 | g->frealloc = f; |
243 | g->ud = ud; | 277 | g->ud = ud; |
244 | g->mainthread = L; | 278 | g->mainthread = L; |
279 | g->seed = makeseed(L); | ||
245 | g->uvhead.u.l.prev = &g->uvhead; | 280 | g->uvhead.u.l.prev = &g->uvhead; |
246 | g->uvhead.u.l.next = &g->uvhead; | 281 | g->uvhead.u.l.next = &g->uvhead; |
247 | g->gcrunning = 0; /* no GC while building state */ | 282 | g->gcrunning = 0; /* no GC while building state */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.h,v 2.75 2012/01/20 22:05:50 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.76 2012/01/25 21:05:40 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -116,6 +116,7 @@ typedef struct global_State { | |||
116 | lu_mem lastmajormem; /* memory in use after last major collection */ | 116 | lu_mem lastmajormem; /* memory in use after last major collection */ |
117 | stringtable strt; /* hash table for strings */ | 117 | stringtable strt; /* hash table for strings */ |
118 | TValue l_registry; | 118 | TValue l_registry; |
119 | unsigned int seed; /* randomized seed for hashes */ | ||
119 | lu_byte currentwhite; | 120 | lu_byte currentwhite; |
120 | lu_byte gcstate; /* state of garbage collector */ | 121 | lu_byte gcstate; /* state of garbage collector */ |
121 | lu_byte gckind; /* kind of GC running */ | 122 | lu_byte gckind; /* kind of GC running */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 2.19 2011/05/03 16:01:57 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 2.21 2012/01/25 21:05:40 roberto Exp roberto $ |
3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -37,8 +37,8 @@ int luaS_eqstr (TString *a, TString *b) { | |||
37 | } | 37 | } |
38 | 38 | ||
39 | 39 | ||
40 | unsigned int luaS_hash (const char *str, size_t l) { | 40 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { |
41 | unsigned int h = cast(unsigned int, l); /* seed */ | 41 | unsigned int h = seed ^ l; |
42 | size_t l1; | 42 | size_t l1; |
43 | for (l1 = 0; l1 < l; l1++) | 43 | for (l1 = 0; l1 < l; l1++) |
44 | h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1])); | 44 | h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1])); |
@@ -120,8 +120,9 @@ static TString *newshrstr (lua_State *L, const char *str, size_t l, | |||
120 | */ | 120 | */ |
121 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { | 121 | static TString *internshrstr (lua_State *L, const char *str, size_t l) { |
122 | GCObject *o; | 122 | GCObject *o; |
123 | unsigned int h = luaS_hash(str, l); | 123 | global_State *g = G(L); |
124 | for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)]; | 124 | unsigned int h = luaS_hash(str, l, g->seed); |
125 | for (o = g->strt.hash[lmod(h, g->strt.size)]; | ||
125 | o != NULL; | 126 | o != NULL; |
126 | o = gch(o)->next) { | 127 | o = gch(o)->next) { |
127 | TString *ts = rawgco2ts(o); | 128 | TString *ts = rawgco2ts(o); |
@@ -146,7 +147,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
146 | else { | 147 | else { |
147 | if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) | 148 | if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) |
148 | luaM_toobig(L); | 149 | luaM_toobig(L); |
149 | return createstrobj(L, str, l, LUA_TLNGSTR, 0, NULL); | 150 | return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL); |
150 | } | 151 | } |
151 | } | 152 | } |
152 | 153 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.h,v 1.46 2010/04/05 16:26:37 roberto Exp roberto $ | 2 | ** $Id: lstring.h,v 1.48 2012/01/25 21:05:40 roberto Exp roberto $ |
3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -34,7 +34,7 @@ | |||
34 | #define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) | 34 | #define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) |
35 | 35 | ||
36 | 36 | ||
37 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l); | 37 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); |
38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); | 38 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); |
39 | LUAI_FUNC int luaS_eqstr (TString *a, TString *b); | 39 | LUAI_FUNC int luaS_eqstr (TString *a, TString *b); |
40 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); | 40 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 2.67 2011/11/30 12:41:45 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.69 2012/01/25 21:05:40 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -101,7 +101,7 @@ static Node *mainposition (const Table *t, const TValue *key) { | |||
101 | case LUA_TLNGSTR: { | 101 | case LUA_TLNGSTR: { |
102 | TString *s = rawtsvalue(key); | 102 | TString *s = rawtsvalue(key); |
103 | if (s->tsv.extra == 0) { /* no hash? */ | 103 | if (s->tsv.extra == 0) { /* no hash? */ |
104 | s->tsv.hash = luaS_hash(getstr(s), s->tsv.len); | 104 | s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash); |
105 | s->tsv.extra = 1; /* now it has its hash */ | 105 | s->tsv.extra = 1; /* now it has its hash */ |
106 | } | 106 | } |
107 | return hashstr(t, rawtsvalue(key)); | 107 | return hashstr(t, rawtsvalue(key)); |