Skip to content

Commit

Permalink
wasmparser: Update validator for custom page sizes (#1575)
Browse files Browse the repository at this point in the history
The CG voted today to conservatively allow only two page sizes: 1 byte and 64
KiB. This updates `wasmparser`'s validation to match that decision.
  • Loading branch information
fitzgen authored May 21, 2024
1 parent 64c0b26 commit f1898f4
Show file tree
Hide file tree
Showing 41 changed files with 360 additions and 561 deletions.
6 changes: 4 additions & 2 deletions crates/wasmparser/src/validator/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -905,12 +905,14 @@ impl Module {
offset,
));
}
if page_size_log2 > 16 {
// Currently 2**0 and 2**16 are the only valid page sizes, but this
// may be relaxed to allow any power of two in the future.
if page_size_log2 != 0 && page_size_log2 != 16 {
return Err(BinaryReaderError::new("invalid custom page size", offset));
}
let page_size = 1_u64 << page_size_log2;
debug_assert!(page_size.is_power_of_two());
debug_assert!(page_size <= DEFAULT_WASM_PAGE_SIZE);
debug_assert!(page_size == DEFAULT_WASM_PAGE_SIZE || page_size == 1);
(page_size, page_size_log2)
} else {
let page_size_log2 = 16;
Expand Down
65 changes: 64 additions & 1 deletion tests/local/custom-page-sizes/custom-page-sizes-invalid.wast
Original file line number Diff line number Diff line change
@@ -1,9 +1,72 @@
;; Page size that is not a power of two.
(assert_malformed
(module quote "(memory 0 (pagesize 3))")
"invalid custom page size"
)

;; Power of two page size that is larger than 64KiB.
;; Power-of-two page sizes that are not 1 or 64KiB.
(assert_invalid
(module (memory 0 (pagesize 2)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 4)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 8)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 16)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 32)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 64)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 128)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 256)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 512)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 1024)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 2048)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 4096)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 8192)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 16384)))
"invalid custom page size"
)
(assert_invalid
(module (memory 0 (pagesize 32768)))
"invalid custom page size"
)

;; Power-of-two page size that is larger than 64KiB.
(assert_invalid
(module (memory 0 (pagesize 0x20000)))
"invalid custom page size"
Expand Down
98 changes: 34 additions & 64 deletions tests/local/custom-page-sizes/custom-page-sizes.wast
Original file line number Diff line number Diff line change
@@ -1,39 +1,9 @@
;; Check all the valid custom page sizes.
(module (memory 1 (pagesize 1)))
(module (memory 1 (pagesize 2)))
(module (memory 1 (pagesize 4)))
(module (memory 1 (pagesize 8)))
(module (memory 1 (pagesize 16)))
(module (memory 1 (pagesize 32)))
(module (memory 1 (pagesize 64)))
(module (memory 1 (pagesize 128)))
(module (memory 1 (pagesize 256)))
(module (memory 1 (pagesize 512)))
(module (memory 1 (pagesize 1024)))
(module (memory 1 (pagesize 2048)))
(module (memory 1 (pagesize 4096)))
(module (memory 1 (pagesize 8192)))
(module (memory 1 (pagesize 16384)))
(module (memory 1 (pagesize 32768)))
(module (memory 1 (pagesize 65536)))

;; Check them all again with maximums specified.
(module (memory 1 2 (pagesize 1)))
(module (memory 1 2 (pagesize 2)))
(module (memory 1 2 (pagesize 4)))
(module (memory 1 2 (pagesize 8)))
(module (memory 1 2 (pagesize 16)))
(module (memory 1 2 (pagesize 32)))
(module (memory 1 2 (pagesize 64)))
(module (memory 1 2 (pagesize 128)))
(module (memory 1 2 (pagesize 256)))
(module (memory 1 2 (pagesize 512)))
(module (memory 1 2 (pagesize 1024)))
(module (memory 1 2 (pagesize 2048)))
(module (memory 1 2 (pagesize 4096)))
(module (memory 1 2 (pagesize 8192)))
(module (memory 1 2 (pagesize 16384)))
(module (memory 1 2 (pagesize 32768)))
(module (memory 1 2 (pagesize 65536)))

;; Check the behavior of memories with page size 1.
Expand Down Expand Up @@ -70,40 +40,6 @@
(assert_return (invoke "load" (i32.const 131071)) (i32.const 1))
(assert_trap (invoke "load" (i32.const 131072)) "out of bounds memory access")

;; Check the behavior of memories with page size 4.
(module
(memory 0 (pagesize 4))
(func (export "size") (result i32)
memory.size
)
(func (export "grow") (param i32) (result i32)
(memory.grow (local.get 0))
)
(func (export "load") (param i32) (result i32)
(i32.load (local.get 0))
)
(func (export "store") (param i32 i32)
(i32.store (local.get 0) (local.get 1))
)
)

(assert_return (invoke "size") (i32.const 0))
(assert_trap (invoke "load" (i32.const 0)) "out of bounds memory access")

(assert_return (invoke "grow" (i32.const 65536)) (i32.const 0))
(assert_return (invoke "size") (i32.const 65536))
(assert_return (invoke "load" (i32.const 262143)) (i32.const 0))
(assert_return (invoke "store" (i32.const 262143) (i32.const 1)))
(assert_return (invoke "load" (i32.const 262143)) (i32.const 1))
(assert_trap (invoke "load" (i32.const 262144)) "out of bounds memory access")

(assert_return (invoke "grow" (i32.const 65536)) (i32.const 65536))
(assert_return (invoke "size") (i32.const 131072))
(assert_return (invoke "load" (i32.const 524287)) (i32.const 0))
(assert_return (invoke "store" (i32.const 524287) (i32.const 1)))
(assert_return (invoke "load" (i32.const 524287)) (i32.const 1))
(assert_trap (invoke "load" (i32.const 524288)) "out of bounds memory access")

;; Although smaller page sizes let us get to memories larger than 2**16 pages,
;; we can't do that with the default page size, even if we explicitly state it
;; as a custom page size.
Expand All @@ -116,3 +52,37 @@
(assert_return (invoke "size") (i32.const 0))
(assert_return (invoke "grow" (i32.const 65537)) (i32.const -1))
(assert_return (invoke "size") (i32.const 0))

;; Can copy between memories of different page sizes.
(module
(memory $small 10 (pagesize 1))
(memory $large 1 (pagesize 65536))

(data (memory $small) (i32.const 0) "\11\22\33\44")
(data (memory $large) (i32.const 0) "\55\66\77\88")

(func (export "copy-small-to-large") (param i32 i32 i32)
(memory.copy $small $large (local.get 0) (local.get 1) (local.get 2))
)

(func (export "copy-large-to-small") (param i32 i32 i32)
(memory.copy $large $small (local.get 0) (local.get 1) (local.get 2))
)

(func (export "load8-small") (param i32) (result i32)
(i32.load8_u (local.get 0))
)

(func (export "load8-large") (param i32) (result i32)
(i32.load8_u (local.get 0))
)
)

(assert_return (invoke "copy-small-to-large") (i32.const 0) (i32.const 2) (i32.const 6))
(assert_return (invoke "load8-large") (i32.const 6) (i32.const 0x11))
(assert_return (invoke "load8-large") (i32.const 7) (i32.const 0x22))

(assert_return (invoke "copy-large-to-small") (i32.const 1) (i32.const 3) (i32.const 4))
(assert_return (invoke "load8-large") (i32.const 4) (i32.const 0x66))
(assert_return (invoke "load8-large") (i32.const 5) (i32.const 0x77))
(assert_return (invoke "load8-large") (i32.const 6) (i32.const 0x88))
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,129 @@
"commands": [
{
"type": "assert_malformed",
"line": 2,
"line": 3,
"filename": "custom-page-sizes-invalid.0.wat",
"text": "invalid custom page size",
"module_type": "text"
},
{
"type": "assert_invalid",
"line": 8,
"line": 9,
"filename": "custom-page-sizes-invalid.1.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_malformed",
"line": 15,
"type": "assert_invalid",
"line": 13,
"filename": "custom-page-sizes-invalid.2.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 17,
"filename": "custom-page-sizes-invalid.3.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 21,
"filename": "custom-page-sizes-invalid.4.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 25,
"filename": "custom-page-sizes-invalid.5.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 29,
"filename": "custom-page-sizes-invalid.6.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 33,
"filename": "custom-page-sizes-invalid.7.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 37,
"filename": "custom-page-sizes-invalid.8.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 41,
"filename": "custom-page-sizes-invalid.9.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 45,
"filename": "custom-page-sizes-invalid.10.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 49,
"filename": "custom-page-sizes-invalid.11.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 53,
"filename": "custom-page-sizes-invalid.12.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 57,
"filename": "custom-page-sizes-invalid.13.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 61,
"filename": "custom-page-sizes-invalid.14.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 65,
"filename": "custom-page-sizes-invalid.15.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_invalid",
"line": 71,
"filename": "custom-page-sizes-invalid.16.wasm",
"text": "invalid custom page size",
"module_type": "binary"
},
{
"type": "assert_malformed",
"line": 78,
"filename": "custom-page-sizes-invalid.17.wasm",
"text": "invalid custom page size",
"module_type": "binary"
}
]
}
Loading

0 comments on commit f1898f4

Please sign in to comment.