Skip to content

Commit 6453fd5

Browse files
authored
Memory flattening: Check for overflow (#6233)
Fixes a fuzz testcase for wasm-ctor-eval. Add the beginnings of a polyfill for stdckdint.h to help that.
1 parent 1ce851d commit 6453fd5

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

src/ir/memory-utils.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
#include "ir/memory-utils.h"
18+
#include "support/stdckdint.h"
1819
#include "wasm.h"
1920

2021
namespace wasm::MemoryUtils {
@@ -94,7 +95,11 @@ bool flatten(Module& wasm) {
9495
for (auto& segment : dataSegments) {
9596
auto* offset = segment->offset->dynCast<Const>();
9697
Index start = offset->value.getInteger();
97-
Index end = start + segment->data.size();
98+
Index size = segment->data.size();
99+
Index end;
100+
if (std::ckd_add(&end, start, size)) {
101+
return false;
102+
}
98103
if (end > data.size()) {
99104
data.resize(end);
100105
}

src/support/stdckdint.h

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2024 WebAssembly Community Group participants
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#ifndef wasm_stdckdint_h
18+
#define wasm_stdckdint_h
19+
20+
// This is a partial "polyfill" for the C23 file stdckdint.h. It allows us to
21+
// use that API even in older compilers.
22+
23+
namespace std {
24+
25+
template<typename T> bool ckd_add(T* output, T a, T b) {
26+
#if __has_builtin(__builtin_add_overflow)
27+
return __builtin_add_overflow(a, b, output);
28+
#else
29+
// Atm this polyfill only supports unsigned types.
30+
static_assert(std::is_unsigned_v<T>);
31+
32+
T result = a + b;
33+
if (result < a) {
34+
return true;
35+
}
36+
*output = result;
37+
return false;
38+
#endif
39+
}
40+
41+
} // namespace std
42+
43+
#endif // wasm_stdckdint_h
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
;; The data segment here is at an offset too large to fit into the memory due
2+
;; to an overflow. That will cause us to fail during flatten, so there are no
3+
;; changes to output here, but we should not error (if we don't check for
4+
;; overflow, we'd segfault).
5+
6+
;; RUN: wasm-ctor-eval %s --ctors=test --kept-exports=test --quiet -all
7+
8+
(module
9+
(memory $0 10 10)
10+
(data $0 (i32.const -1) "a")
11+
12+
(export "test" (func $test))
13+
14+
(func $test
15+
)
16+
)

0 commit comments

Comments
 (0)