aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-02-01 19:57:15 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2012-02-01 19:57:15 -0200
commit678c1255c92eed9c2c7564d340a5563b17395158 (patch)
treeca35d119d770835b59d34cdec93805190d3155d1
parenta4b96ce9a3305ae3585c0bb143fa7342c140f20b (diff)
downloadlua-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.c37
-rw-r--r--lstate.h3
-rw-r--r--lstring.c13
-rw-r--r--lstring.h4
-rw-r--r--ltable.c4
5 files changed, 49 insertions, 12 deletions
diff --git a/lstate.c b/lstate.c
index bc13897b..5031a0a1 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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*/
47typedef struct LX { 59typedef 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
89static 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 */
diff --git a/lstate.h b/lstate.h
index 38a7fb36..f6c093b3 100644
--- a/lstate.h
+++ b/lstate.h
@@ -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 */
diff --git a/lstring.c b/lstring.c
index 75861cf4..a704af4e 100644
--- a/lstring.c
+++ b/lstring.c
@@ -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
40unsigned int luaS_hash (const char *str, size_t l) { 40unsigned 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*/
121static TString *internshrstr (lua_State *L, const char *str, size_t l) { 121static 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
diff --git a/lstring.h b/lstring.h
index 6cfcbfcc..b52a9356 100644
--- a/lstring.h
+++ b/lstring.h
@@ -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
37LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l); 37LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
38LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); 38LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
39LUAI_FUNC int luaS_eqstr (TString *a, TString *b); 39LUAI_FUNC int luaS_eqstr (TString *a, TString *b);
40LUAI_FUNC void luaS_resize (lua_State *L, int newsize); 40LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
diff --git a/ltable.c b/ltable.c
index 3683fe60..adccb0a7 100644
--- a/ltable.c
+++ b/ltable.c
@@ -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));