Closed Bug 645673 Opened 13 years ago Closed 6 years ago

Object initialization can reveal zero'd memory

Categories

(Tamarin Graveyard :: Virtual Machine, defect)

defect
Not set
normal

Tracking

(Not tracked)

RESOLVED WONTFIX

People

(Reporter: edwsmith, Unassigned)

References

Details

(Whiteboard: PACMAN)

Object initialization can expose code to fields containing all 
zeros.  This means:

* A field of type Number can be observed as 0.0 before being
properly initialized to NaN

* A field of type * can be observed holding 0 (0|kUnusedAtomTag)
before being initialized to undefined.

* If the traits for an int, uint, Number, Boolean, Namespace, or String
field contains a nonzero default value, then the field can be observed
as 0|0.0|false|null before having the default value.

  class A { ... }
  class B extends A { ... }

1. memory is allocated and zerod
2. B.B() is invoked, and the first thing it does is initialize
   B's slots to default values.
3. At some point (possibly never) constructsuper is called, and
   the first thing A.A() does is initialize A's slots.

Between step 2 and 3, user code can execute, peek into A's fields
and observe zero'd memory before the field gets its default value.

In all cases except a field of type *, the zero'd memory represents
a valid value for the given type.  However, the value (0|kUnusedAtomTag)
is not a valid value; it is treated as null by defensive code, but its semantics aren't clear.
Blocks: 645677
Proposed versioned fix:

initializing slots to constant values from their traits is part of allocation, not initialization.  Immediately after allocating an object, the caller initializes all slots, including base classes, to their default values.

old versions:
 - slots that would have received invalid 0 atoms now become nullObjectAtom
 - init method still begin with vm-generated initializer code.  it is redundant but compatible.

new versions:
 - slots get their proper default value, e.g. undefined or NaN, or whatever is in their Trait
 - no vm-generated code is prepended to the user initializer.

The version decision is static, based on the version of abc, *not* based on the call stack.

idea from Lars: the init code can store pointers without write barriers, if the sequence ends with a check to see if the object is marked and a callout that scans the pointer fields.  the check+fixup could be omitted if there are pointer fields that don't hold pointers (ie, null) or if there aren't pointers.
what if the base class is old and the subclass is new, or vice versa?
adding PACMAN on the speculation this will speed up object allocation, although if the init code just moves around, it may be a wash.
Whiteboard: PACMAN
Blocks: 531250
Blocks: 587977
Tamarin is a dead project now. Mass WONTFIX.
Status: NEW → RESOLVED
Closed: 6 years ago
Resolution: --- → WONTFIX
Tamarin isn't maintained anymore. WONTFIX remaining bugs.
You need to log in before you can comment on or make changes to this bug.