Skip to content

Commit f1898f4

Browse files
authored
wasmparser: Update validator for custom page sizes (#1575)
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.
1 parent 64c0b26 commit f1898f4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+360
-561
lines changed

crates/wasmparser/src/validator/core.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -905,12 +905,14 @@ impl Module {
905905
offset,
906906
));
907907
}
908-
if page_size_log2 > 16 {
908+
// Currently 2**0 and 2**16 are the only valid page sizes, but this
909+
// may be relaxed to allow any power of two in the future.
910+
if page_size_log2 != 0 && page_size_log2 != 16 {
909911
return Err(BinaryReaderError::new("invalid custom page size", offset));
910912
}
911913
let page_size = 1_u64 << page_size_log2;
912914
debug_assert!(page_size.is_power_of_two());
913-
debug_assert!(page_size <= DEFAULT_WASM_PAGE_SIZE);
915+
debug_assert!(page_size == DEFAULT_WASM_PAGE_SIZE || page_size == 1);
914916
(page_size, page_size_log2)
915917
} else {
916918
let page_size_log2 = 16;

tests/local/custom-page-sizes/custom-page-sizes-invalid.wast

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,72 @@
1+
;; Page size that is not a power of two.
12
(assert_malformed
23
(module quote "(memory 0 (pagesize 3))")
34
"invalid custom page size"
45
)
56

6-
;; Power of two page size that is larger than 64KiB.
7+
;; Power-of-two page sizes that are not 1 or 64KiB.
8+
(assert_invalid
9+
(module (memory 0 (pagesize 2)))
10+
"invalid custom page size"
11+
)
12+
(assert_invalid
13+
(module (memory 0 (pagesize 4)))
14+
"invalid custom page size"
15+
)
16+
(assert_invalid
17+
(module (memory 0 (pagesize 8)))
18+
"invalid custom page size"
19+
)
20+
(assert_invalid
21+
(module (memory 0 (pagesize 16)))
22+
"invalid custom page size"
23+
)
24+
(assert_invalid
25+
(module (memory 0 (pagesize 32)))
26+
"invalid custom page size"
27+
)
28+
(assert_invalid
29+
(module (memory 0 (pagesize 64)))
30+
"invalid custom page size"
31+
)
32+
(assert_invalid
33+
(module (memory 0 (pagesize 128)))
34+
"invalid custom page size"
35+
)
36+
(assert_invalid
37+
(module (memory 0 (pagesize 256)))
38+
"invalid custom page size"
39+
)
40+
(assert_invalid
41+
(module (memory 0 (pagesize 512)))
42+
"invalid custom page size"
43+
)
44+
(assert_invalid
45+
(module (memory 0 (pagesize 1024)))
46+
"invalid custom page size"
47+
)
48+
(assert_invalid
49+
(module (memory 0 (pagesize 2048)))
50+
"invalid custom page size"
51+
)
52+
(assert_invalid
53+
(module (memory 0 (pagesize 4096)))
54+
"invalid custom page size"
55+
)
56+
(assert_invalid
57+
(module (memory 0 (pagesize 8192)))
58+
"invalid custom page size"
59+
)
60+
(assert_invalid
61+
(module (memory 0 (pagesize 16384)))
62+
"invalid custom page size"
63+
)
64+
(assert_invalid
65+
(module (memory 0 (pagesize 32768)))
66+
"invalid custom page size"
67+
)
68+
69+
;; Power-of-two page size that is larger than 64KiB.
770
(assert_invalid
871
(module (memory 0 (pagesize 0x20000)))
972
"invalid custom page size"
Lines changed: 34 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,9 @@
11
;; Check all the valid custom page sizes.
22
(module (memory 1 (pagesize 1)))
3-
(module (memory 1 (pagesize 2)))
4-
(module (memory 1 (pagesize 4)))
5-
(module (memory 1 (pagesize 8)))
6-
(module (memory 1 (pagesize 16)))
7-
(module (memory 1 (pagesize 32)))
8-
(module (memory 1 (pagesize 64)))
9-
(module (memory 1 (pagesize 128)))
10-
(module (memory 1 (pagesize 256)))
11-
(module (memory 1 (pagesize 512)))
12-
(module (memory 1 (pagesize 1024)))
13-
(module (memory 1 (pagesize 2048)))
14-
(module (memory 1 (pagesize 4096)))
15-
(module (memory 1 (pagesize 8192)))
16-
(module (memory 1 (pagesize 16384)))
17-
(module (memory 1 (pagesize 32768)))
183
(module (memory 1 (pagesize 65536)))
194

205
;; Check them all again with maximums specified.
216
(module (memory 1 2 (pagesize 1)))
22-
(module (memory 1 2 (pagesize 2)))
23-
(module (memory 1 2 (pagesize 4)))
24-
(module (memory 1 2 (pagesize 8)))
25-
(module (memory 1 2 (pagesize 16)))
26-
(module (memory 1 2 (pagesize 32)))
27-
(module (memory 1 2 (pagesize 64)))
28-
(module (memory 1 2 (pagesize 128)))
29-
(module (memory 1 2 (pagesize 256)))
30-
(module (memory 1 2 (pagesize 512)))
31-
(module (memory 1 2 (pagesize 1024)))
32-
(module (memory 1 2 (pagesize 2048)))
33-
(module (memory 1 2 (pagesize 4096)))
34-
(module (memory 1 2 (pagesize 8192)))
35-
(module (memory 1 2 (pagesize 16384)))
36-
(module (memory 1 2 (pagesize 32768)))
377
(module (memory 1 2 (pagesize 65536)))
388

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

73-
;; Check the behavior of memories with page size 4.
74-
(module
75-
(memory 0 (pagesize 4))
76-
(func (export "size") (result i32)
77-
memory.size
78-
)
79-
(func (export "grow") (param i32) (result i32)
80-
(memory.grow (local.get 0))
81-
)
82-
(func (export "load") (param i32) (result i32)
83-
(i32.load (local.get 0))
84-
)
85-
(func (export "store") (param i32 i32)
86-
(i32.store (local.get 0) (local.get 1))
87-
)
88-
)
89-
90-
(assert_return (invoke "size") (i32.const 0))
91-
(assert_trap (invoke "load" (i32.const 0)) "out of bounds memory access")
92-
93-
(assert_return (invoke "grow" (i32.const 65536)) (i32.const 0))
94-
(assert_return (invoke "size") (i32.const 65536))
95-
(assert_return (invoke "load" (i32.const 262143)) (i32.const 0))
96-
(assert_return (invoke "store" (i32.const 262143) (i32.const 1)))
97-
(assert_return (invoke "load" (i32.const 262143)) (i32.const 1))
98-
(assert_trap (invoke "load" (i32.const 262144)) "out of bounds memory access")
99-
100-
(assert_return (invoke "grow" (i32.const 65536)) (i32.const 65536))
101-
(assert_return (invoke "size") (i32.const 131072))
102-
(assert_return (invoke "load" (i32.const 524287)) (i32.const 0))
103-
(assert_return (invoke "store" (i32.const 524287) (i32.const 1)))
104-
(assert_return (invoke "load" (i32.const 524287)) (i32.const 1))
105-
(assert_trap (invoke "load" (i32.const 524288)) "out of bounds memory access")
106-
10743
;; Although smaller page sizes let us get to memories larger than 2**16 pages,
10844
;; we can't do that with the default page size, even if we explicitly state it
10945
;; as a custom page size.
@@ -116,3 +52,37 @@
11652
(assert_return (invoke "size") (i32.const 0))
11753
(assert_return (invoke "grow" (i32.const 65537)) (i32.const -1))
11854
(assert_return (invoke "size") (i32.const 0))
55+
56+
;; Can copy between memories of different page sizes.
57+
(module
58+
(memory $small 10 (pagesize 1))
59+
(memory $large 1 (pagesize 65536))
60+
61+
(data (memory $small) (i32.const 0) "\11\22\33\44")
62+
(data (memory $large) (i32.const 0) "\55\66\77\88")
63+
64+
(func (export "copy-small-to-large") (param i32 i32 i32)
65+
(memory.copy $small $large (local.get 0) (local.get 1) (local.get 2))
66+
)
67+
68+
(func (export "copy-large-to-small") (param i32 i32 i32)
69+
(memory.copy $large $small (local.get 0) (local.get 1) (local.get 2))
70+
)
71+
72+
(func (export "load8-small") (param i32) (result i32)
73+
(i32.load8_u (local.get 0))
74+
)
75+
76+
(func (export "load8-large") (param i32) (result i32)
77+
(i32.load8_u (local.get 0))
78+
)
79+
)
80+
81+
(assert_return (invoke "copy-small-to-large") (i32.const 0) (i32.const 2) (i32.const 6))
82+
(assert_return (invoke "load8-large") (i32.const 6) (i32.const 0x11))
83+
(assert_return (invoke "load8-large") (i32.const 7) (i32.const 0x22))
84+
85+
(assert_return (invoke "copy-large-to-small") (i32.const 1) (i32.const 3) (i32.const 4))
86+
(assert_return (invoke "load8-large") (i32.const 4) (i32.const 0x66))
87+
(assert_return (invoke "load8-large") (i32.const 5) (i32.const 0x77))
88+
(assert_return (invoke "load8-large") (i32.const 6) (i32.const 0x88))

tests/snapshots/local/custom-page-sizes/custom-page-sizes-invalid.wast.json

Lines changed: 109 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,129 @@
33
"commands": [
44
{
55
"type": "assert_malformed",
6-
"line": 2,
6+
"line": 3,
77
"filename": "custom-page-sizes-invalid.0.wat",
88
"text": "invalid custom page size",
99
"module_type": "text"
1010
},
1111
{
1212
"type": "assert_invalid",
13-
"line": 8,
13+
"line": 9,
1414
"filename": "custom-page-sizes-invalid.1.wasm",
1515
"text": "invalid custom page size",
1616
"module_type": "binary"
1717
},
1818
{
19-
"type": "assert_malformed",
20-
"line": 15,
19+
"type": "assert_invalid",
20+
"line": 13,
2121
"filename": "custom-page-sizes-invalid.2.wasm",
2222
"text": "invalid custom page size",
2323
"module_type": "binary"
24+
},
25+
{
26+
"type": "assert_invalid",
27+
"line": 17,
28+
"filename": "custom-page-sizes-invalid.3.wasm",
29+
"text": "invalid custom page size",
30+
"module_type": "binary"
31+
},
32+
{
33+
"type": "assert_invalid",
34+
"line": 21,
35+
"filename": "custom-page-sizes-invalid.4.wasm",
36+
"text": "invalid custom page size",
37+
"module_type": "binary"
38+
},
39+
{
40+
"type": "assert_invalid",
41+
"line": 25,
42+
"filename": "custom-page-sizes-invalid.5.wasm",
43+
"text": "invalid custom page size",
44+
"module_type": "binary"
45+
},
46+
{
47+
"type": "assert_invalid",
48+
"line": 29,
49+
"filename": "custom-page-sizes-invalid.6.wasm",
50+
"text": "invalid custom page size",
51+
"module_type": "binary"
52+
},
53+
{
54+
"type": "assert_invalid",
55+
"line": 33,
56+
"filename": "custom-page-sizes-invalid.7.wasm",
57+
"text": "invalid custom page size",
58+
"module_type": "binary"
59+
},
60+
{
61+
"type": "assert_invalid",
62+
"line": 37,
63+
"filename": "custom-page-sizes-invalid.8.wasm",
64+
"text": "invalid custom page size",
65+
"module_type": "binary"
66+
},
67+
{
68+
"type": "assert_invalid",
69+
"line": 41,
70+
"filename": "custom-page-sizes-invalid.9.wasm",
71+
"text": "invalid custom page size",
72+
"module_type": "binary"
73+
},
74+
{
75+
"type": "assert_invalid",
76+
"line": 45,
77+
"filename": "custom-page-sizes-invalid.10.wasm",
78+
"text": "invalid custom page size",
79+
"module_type": "binary"
80+
},
81+
{
82+
"type": "assert_invalid",
83+
"line": 49,
84+
"filename": "custom-page-sizes-invalid.11.wasm",
85+
"text": "invalid custom page size",
86+
"module_type": "binary"
87+
},
88+
{
89+
"type": "assert_invalid",
90+
"line": 53,
91+
"filename": "custom-page-sizes-invalid.12.wasm",
92+
"text": "invalid custom page size",
93+
"module_type": "binary"
94+
},
95+
{
96+
"type": "assert_invalid",
97+
"line": 57,
98+
"filename": "custom-page-sizes-invalid.13.wasm",
99+
"text": "invalid custom page size",
100+
"module_type": "binary"
101+
},
102+
{
103+
"type": "assert_invalid",
104+
"line": 61,
105+
"filename": "custom-page-sizes-invalid.14.wasm",
106+
"text": "invalid custom page size",
107+
"module_type": "binary"
108+
},
109+
{
110+
"type": "assert_invalid",
111+
"line": 65,
112+
"filename": "custom-page-sizes-invalid.15.wasm",
113+
"text": "invalid custom page size",
114+
"module_type": "binary"
115+
},
116+
{
117+
"type": "assert_invalid",
118+
"line": 71,
119+
"filename": "custom-page-sizes-invalid.16.wasm",
120+
"text": "invalid custom page size",
121+
"module_type": "binary"
122+
},
123+
{
124+
"type": "assert_malformed",
125+
"line": 78,
126+
"filename": "custom-page-sizes-invalid.17.wasm",
127+
"text": "invalid custom page size",
128+
"module_type": "binary"
24129
}
25130
]
26131
}

0 commit comments

Comments
 (0)