set a bit to prevent corruption of flags via hashing

Certain datatypes in the runtime system are not supposed
to be hashed, where bits normally reserved for hash codes
are used for other purposes. A bad bytecode file can cause
some of those to be hashed, anyway. Normally, the damage is
isolated to that content of the damaged bytecode, but
certain variable-reference bytecode forms are both shared
and non-hashable. Set a bit that ensures hashing will not
change flags in the shared object.

This problem was exposed by fuzz testing.
This commit is contained in:
Matthew Flatt 2015-10-12 19:25:27 -06:00
parent 42eb8ae332
commit 20f31fb742
2 changed files with 8 additions and 6 deletions

View File

@ -630,7 +630,7 @@ Scheme_Object *scheme_make_toplevel(mzshort depth, int position, int resolved, i
tl->iso.so.type = (resolved ? scheme_toplevel_type : scheme_compiled_toplevel_type);
tl->depth = depth;
tl->position = position;
SCHEME_TOPLEVEL_FLAGS(tl) = flags;
SCHEME_TOPLEVEL_FLAGS(tl) = flags | HIGH_BIT_TO_DISABLE_HASHING;
if (resolved) {
if (toplevels_ht->count > TABLE_CACHE_MAX_SIZE) {
@ -801,7 +801,7 @@ static void init_scheme_local()
#endif
v->type = k + scheme_local_type;
SCHEME_LOCAL_POS(v) = i;
SCHEME_LOCAL_FLAGS(v) = cor;
SCHEME_LOCAL_FLAGS(v) = cor | HIGH_BIT_TO_DISABLE_HASHING;
scheme_local[i][k][cor] = v;
}
@ -841,7 +841,7 @@ static void init_toplevels()
v->iso.so.type = scheme_toplevel_type;
v->depth = i;
v->position = k;
SCHEME_TOPLEVEL_FLAGS(v) = cnst;
SCHEME_TOPLEVEL_FLAGS(v) = cnst | HIGH_BIT_TO_DISABLE_HASHING;
toplevels[i][k][cnst] = (Scheme_Object *)v;
}
@ -888,7 +888,7 @@ Scheme_Object *scheme_make_local(Scheme_Type type, int pos, int flags)
return v;
v = alloc_local(type, pos);
SCHEME_LOCAL_FLAGS(v) = flags;
SCHEME_LOCAL_FLAGS(v) = flags | HIGH_BIT_TO_DISABLE_HASHING;
if (locals_ht[k]->count > TABLE_CACHE_MAX_SIZE) {
Scheme_Hash_Table *ht;

View File

@ -1495,6 +1495,8 @@ typedef struct {
Scheme_Object *body;
} Scheme_With_Continuation_Mark;
#define HIGH_BIT_TO_DISABLE_HASHING 0x2000
typedef struct Scheme_Local {
Scheme_Inclhash_Object iso; /* keyex used for flags and type info (and can't be hashed) */
mzshort position;
@ -1513,8 +1515,8 @@ typedef struct Scheme_Local {
#define SCHEME_LOCAL_OTHER_CLEARS 2
#define SCHEME_LOCAL_TYPE_OFFSET 2
#define SCHEME_GET_LOCAL_FLAGS(obj) SCHEME_LOCAL_FLAGS(obj)
#define SCHEME_GET_LOCAL_TYPE(obj) ((SCHEME_LOCAL_FLAGS(obj) > 2) ? (SCHEME_LOCAL_FLAGS(obj) - 2) : 0)
#define SCHEME_GET_LOCAL_FLAGS(obj) (SCHEME_LOCAL_FLAGS(obj) & ~HIGH_BIT_TO_DISABLE_HASHING)
#define SCHEME_GET_LOCAL_TYPE(obj) ((SCHEME_GET_LOCAL_FLAGS(obj) > 2) ? (SCHEME_GET_LOCAL_FLAGS(obj) - 2) : 0)
typedef struct Scheme_Toplevel {
Scheme_Inclhash_Object iso; /* keyex used for flags (and can't be hashed) */