From 8f661453c3f38edf5b08aee278f030c26134110e Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 30 Jan 2024 10:55:58 -0800 Subject: [PATCH] fix --- src/ir/table-utils.h | 9 +- test/lit/passes/directize_all-features.wast | 174 ++++++++++++++++++++ 2 files changed, 182 insertions(+), 1 deletion(-) diff --git a/src/ir/table-utils.h b/src/ir/table-utils.h index a94691e9f97..5299ba3e106 100644 --- a/src/ir/table-utils.h +++ b/src/ir/table-utils.h @@ -20,6 +20,7 @@ #include "ir/element-utils.h" #include "ir/literal-utils.h" #include "ir/module-utils.h" +#include "support/stdckdint.h" #include "wasm-traversal.h" #include "wasm.h" @@ -40,7 +41,13 @@ struct FlatTable { return; } Index start = offset->cast()->value.geti32(); - Index end = start + segment->data.size(); + Index size = segment->data.size(); + Index end; + if (std::ckd_add(&end, start, size) || end > table.initial) { + // Overflow. + valid = false; + return; + } if (end > names.size()) { names.resize(end); } diff --git a/test/lit/passes/directize_all-features.wast b/test/lit/passes/directize_all-features.wast index 706a86c4656..1e46e42c17e 100644 --- a/test/lit/passes/directize_all-features.wast +++ b/test/lit/passes/directize_all-features.wast @@ -1586,3 +1586,177 @@ ) ) ) + +;; The elem's offset is way out of bounds, which we should not error on, and do +;; nothing otherwise. +(module + ;; CHECK: (type $v (func)) + ;; IMMUT: (type $v (func)) + (type $v (func)) + + (table 10 10 funcref) + + (elem (i32.const -1) $0) + + ;; CHECK: (table $0 10 10 funcref) + + ;; CHECK: (elem $0 (i32.const -1) $0) + + ;; CHECK: (func $0 (type $v) + ;; CHECK-NEXT: (call_indirect $0 (type $v) + ;; CHECK-NEXT: (i32.const -1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; IMMUT: (table $0 10 10 funcref) + + ;; IMMUT: (elem $0 (i32.const -1) $0) + + ;; IMMUT: (func $0 (type $v) + ;; IMMUT-NEXT: (call_indirect $0 (type $v) + ;; IMMUT-NEXT: (i32.const -1) + ;; IMMUT-NEXT: ) + ;; IMMUT-NEXT: ) + (func $0 + (call_indirect (type $v) + (i32.const -1) + ) + ) +) + +;; Another elem offset that is way out of bounds. +(module + ;; CHECK: (type $v (func)) + ;; IMMUT: (type $v (func)) + (type $v (func)) + + (table 10 10 funcref) + + (elem (i32.const -2) $0) + + ;; CHECK: (table $0 10 10 funcref) + + ;; CHECK: (elem $0 (i32.const -2) $0) + + ;; CHECK: (func $0 (type $v) + ;; CHECK-NEXT: (call_indirect $0 (type $v) + ;; CHECK-NEXT: (i32.const -2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; IMMUT: (table $0 10 10 funcref) + + ;; IMMUT: (elem $0 (i32.const -2) $0) + + ;; IMMUT: (func $0 (type $v) + ;; IMMUT-NEXT: (call_indirect $0 (type $v) + ;; IMMUT-NEXT: (i32.const -2) + ;; IMMUT-NEXT: ) + ;; IMMUT-NEXT: ) + (func $0 + (call_indirect (type $v) + (i32.const -2) + ) + ) +) + +;; The elem is just out of bounds due to its offset. +(module + ;; CHECK: (type $v (func)) + ;; IMMUT: (type $v (func)) + (type $v (func)) + + (table 10 10 funcref) + + (elem (i32.const 10) $0) + + ;; CHECK: (table $0 10 10 funcref) + + ;; CHECK: (elem $0 (i32.const 10) $0) + + ;; CHECK: (func $0 (type $v) + ;; CHECK-NEXT: (call_indirect $0 (type $v) + ;; CHECK-NEXT: (i32.const 10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; IMMUT: (table $0 10 10 funcref) + + ;; IMMUT: (elem $0 (i32.const 10) $0) + + ;; IMMUT: (func $0 (type $v) + ;; IMMUT-NEXT: (call_indirect $0 (type $v) + ;; IMMUT-NEXT: (i32.const 10) + ;; IMMUT-NEXT: ) + ;; IMMUT-NEXT: ) + (func $0 + (call_indirect (type $v) + (i32.const 10) + ) + ) +) + +;; The elem is just out of bounds due to its length. +(module + ;; CHECK: (type $v (func)) + ;; IMMUT: (type $v (func)) + (type $v (func)) + + (table 10 10 funcref) + + (elem (i32.const 9) $0 $0) + + ;; CHECK: (table $0 10 10 funcref) + + ;; CHECK: (elem $0 (i32.const 9) $0 $0) + + ;; CHECK: (func $0 (type $v) + ;; CHECK-NEXT: (call_indirect $0 (type $v) + ;; CHECK-NEXT: (i32.const 9) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; IMMUT: (table $0 10 10 funcref) + + ;; IMMUT: (elem $0 (i32.const 9) $0 $0) + + ;; IMMUT: (func $0 (type $v) + ;; IMMUT-NEXT: (call_indirect $0 (type $v) + ;; IMMUT-NEXT: (i32.const 9) + ;; IMMUT-NEXT: ) + ;; IMMUT-NEXT: ) + (func $0 + (call_indirect (type $v) + ;; We could in theory optimize this, as the out of bounds part is after us, + ;; but the wasm traps anyhow, so leave it alone. + (i32.const 9) + ) + ) +) + +;; The elem is ok, and we can optimize. +(module + ;; CHECK: (type $v (func)) + ;; IMMUT: (type $v (func)) + (type $v (func)) + + (table 10 10 funcref) + + (elem (i32.const 9) $0) + + ;; CHECK: (table $0 10 10 funcref) + + ;; CHECK: (elem $0 (i32.const 9) $0) + + ;; CHECK: (func $0 (type $v) + ;; CHECK-NEXT: (call $0) + ;; CHECK-NEXT: ) + ;; IMMUT: (table $0 10 10 funcref) + + ;; IMMUT: (elem $0 (i32.const 9) $0) + + ;; IMMUT: (func $0 (type $v) + ;; IMMUT-NEXT: (call $0) + ;; IMMUT-NEXT: ) + (func $0 + (call_indirect (type $v) + (i32.const 9) + ) + ) +)