CVE-2023-26489 in wasmtime
Tóm tắt
Bởi VulDB • 31/05/2026
wasmtime là một môi trường thực thi nhanh và bảo mật cho WebAssembly. Trong các phiên bản bị ảnh hưởng, trình tạo mã (code generator) của wasmtime, Cranelift, có một lỗi trên các mục tiêu x86_64, trong đó việc tính toán chế độ địa chỉ (address-mode computation) sai lầm sẽ tính ra một địa chỉ hiệu dụng 35-bit thay vì địa chỉ hiệu dụng 33-bit được định nghĩa bởi WebAssembly. Lỗi này có nghĩa là, với các cài đặt codegen mặc định, một thao tác load/store được điều khiển bởi wasm có thể đọc/ghi các địa chỉ cách xa tới 35 bit so với gốc của bộ nhớ tuyến tính (linear memory). Tuy nhiên, do lỗi này, các địa chỉ cách xa tới `0xffffffff * 8 + 0x7ffffffc = 36507222004 = ~34G` byte so với gốc của bộ nhớ tuyến tính đều có thể truy cập được từ mã của guest. Điều này có nghĩa là vùng bộ nhớ ảo cách xa 6G so với gốc của bộ nhớ tuyến tính đến ~34G có thể bị đọc/ghi bởi một mô-đun độc hại. Một mô-đun guest có thể đọc/ghi bộ nhớ trong vùng này mà không cần sự biết đến của embedder. Bộ nhớ này có thể thuộc về các thể hiện WebAssembly khác khi sử dụng bộ phân bổ pooling (pooling allocator), ví dụ. Các embedder bị ảnh hưởng được khuyến nghị phân tích các mô-đun wasm hiện có để xem liệu chúng có bị ảnh hưởng bởi các quy tắc codegen sai lệch hay không và có thể tương quan điều đó với số lượng trap bất thường trong quá trình thực thi lịch sử để xác định các mô-đun đáng ngờ. Lỗi cụ thể trong backend x86_64 của Cranelift là một địa chỉ WebAssembly, khi được dịch trái (left-shifted) bởi một hằng số từ 1 đến 3, sẽ được gộp vào các chế độ địa chỉ của x86_64 thực hiện các phép dịch. Ví dụ, `(i32.load (i32.shl (local.get 0) (i32.const 3)))` tải từ địa chỉ WebAssembly `$local0 << 3`. Khi được dịch sang Cranelift, phép tính `$local0 << 3`, một giá trị 32-bit, được mở rộng không dấu (zero-extended) thành giá trị 64-bit và sau đó được cộng với địa chỉ gốc của bộ nhớ tuyến tính. Cranelift sẽ tạo ra một lệnh có dạng `movl (%base, %local0, 8), %dst`, tính toán `%base + %local0 << 3`. Tuy nhiên, lỗi ở đây là việc tính toán địa chỉ xảy ra với các giá trị 64-bit, trong khi phép tính `$local0 << 3` lẽ ra phải được cắt ngắn (truncated) thành một giá trị 32-bit. Điều này có nghĩa là `%local0`, có thể sử dụng tới 32-bit cho một địa chỉ, sẽ có thêm 3 bit không gian địa chỉ có thể truy cập được thông qua lệnh `movl` này. Bản sửa lỗi trong Cranelift là loại bỏ các quy tắc hạ cấp (lowering rules) sai lầm trong backend xử lý các biểu thức được mở rộng không dấu này. Ví dụ trên sau đó được dịch sang `movl %local0, %temp; shl $3, %temp; movl (%base, %temp), %dst`, điều này cắt ngắn đúng cách phép tính trung gian của `%local0 << 3` xuống 32-bit bên trong thanh ghi `%temp`, sau đó được cộng với `%base` để tạo ra địa chỉ hiệu dụng 32-bit.
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.