// This tests 8- and 16-bit field accesses for structs.
// Check that struct.new writes for 8-bit fields do not overwrite subsequent // data. Because the writes happen forwards in the address space, the only // way I could think to do this is to force an 8-bit field to occupy the last // byte of the OOL malloc'd block, and then hope that ASan runs in automation // will pick up any overrun. I think it's impossible to test this from inside // the JS+wasm universe. Hence the test is pretty pointless from a purely // JS+wasm interpretation.
{
let txt =
`(module
(type $hasOOL (struct
;; In-line storage; 16 fields that preserve 16-alignment
(field i64) (field i64) (field i64) (field i64) ;; 32
(field i64) (field i64) (field i64) (field i64) ;; 64
(field i64) (field i64) (field i64) (field i64) ;; 96
(field i64) (field i64) (field i64) (field i64) ;; 128
;; Out-of-line storage (or maybe it starts earlier, but
;; definitely not after this point). 16 bytes on the
;; basis that StructLayout::close will round the requested
;; block size up to at max the next 16 byte boundary.
;; The goal is that the last (field i8) is right at the
;; end of the resulting malloc'd block, so that, if the
;; struct.new initialisation code mistakenly initialises
;; that field with a write larger than 8 bits, then we'll
;; have a write off the end of the malloc'd block, which
;; ASan automation runs should detect.
(field i8) (field i8) (field i8) (field i8)
(field i8) (field i8) (field i8) (field i8)
(field i8) (field i8) (field i8) (field i8)
(field i8) (field i8) (field i8) (field i8))
)
(func (export "build8")
(param $filler i64) (param $interesting i32) (result eqref)
(struct.new $hasOOL
(local.get $filler) (local.get $filler)
(local.get $filler) (local.get $filler)
(local.get $filler) (local.get $filler)
(local.get $filler) (local.get $filler)
(local.get $filler) (local.get $filler)
(local.get $filler) (local.get $filler)
(local.get $filler) (local.get $filler)
(local.get $filler) (local.get $filler)
(local.get $interesting) (local.get $interesting)
(local.get $interesting) (local.get $interesting)
(local.get $interesting) (local.get $interesting)
(local.get $interesting) (local.get $interesting)
(local.get $interesting) (local.get $interesting)
(local.get $interesting) (local.get $interesting)
(local.get $interesting) (local.get $interesting)
(local.get $interesting) (local.get $interesting)
)
)
)`;
let exports = wasmEvalText(txt).exports;
let obj8 = exports.build8(0x1234n, 0x5678); // The above call should trigger OOB writes if the struct.new field // writes are too large, but those will only be visible if we're running // on ASan or Valgrind. In any case, add a fake data dependency below, so // that the construction of the object can't (so easily) be optimised away.
assertEq(wasmGcReadField(obj8, 0) + BigInt(wasmGcReadField(obj8, 31)), 0x12ACn); // == 0x1234 + 0x78
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.