Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

AlignmentLowering: an out-of-bounds unaligned store becomes a partial write

オープン
#9,186 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
52/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
wasm
領域
compilers

調査の方向性

Start by locating the AlignmentLowering and i64-to-i32-lowering implementations, then run the provided wasm-opt reproducer with --alignment-lowering and --fuzz-exec. Check both affected passes for multi-byte stores near the memory boundary. Done means an out-of-bounds store traps without modifying memory in both passes, while valid stores retain their behavior.

索引モデルが issue の本文から書いたものです。

説明

Summary

An unaligned i32.store align=1 is split into four i32.store8s. If the address is out of bounds, the first bytes are written and the later ones trap, so memory differs after the trap. In the spec, a store whose bytes do not all fit in the memory reduces to trap without changing the store (Step/store-num-oob), so a trapping store never writes anything.

Root cause

The byte stores are emitted in increasing address order. The last byte is the one that traps, and the earlier stores have already happened.

Affected passes

--alignment-lowering and --i64-to-i32-lowering. The latter writes the low word of an i64.store before the high word traps.

Reproducer
(module
 (memory 1 1)
 (func (export "store")
  (i32.store align=1 (i32.const 65534) (i32.const 0x01020304)))
 (func (export "peek") (result i32)
  (i32.load (i32.const 65532))))
$ wasm-opt in.wat --alignment-lowering --print
 (func $0
  (local $0 i32)
  (local $1 i32)
  (local.set $0 (i32.const 65534))
  (local.set $1 (i32.const 16909060))
  (i32.store8 (local.get $0) (local.get $1))
  (i32.store8 offset=1 (local.get $0) (i32.shr_u (local.get $1) (i32.const 8)))
  (i32.store8 offset=2 (local.get $0) (i32.shr_u (local.get $1) (i32.const 16)))
  (i32.store8 offset=3 (local.get $0) (i32.shr_u (local.get $1) (i32.const 24)))
 )

The 4-byte store at 65534 in a 1-page memory is out of bounds, so it must trap without writing. peek reads the last word afterwards:

$ wasm-opt in.wat --alignment-lowering --fuzz-exec -o /dev/null
[fuzz-exec] export store
[trap highest > memory: 65534 > 65532]
[fuzz-exec] export peek
[fuzz-exec] note result: peek => 0
[fuzz-exec] export store
[trap highest > memory: 65536 > 65535]
[fuzz-exec] export peek
[fuzz-exec] note result: peek => 50593792
[fuzz-exec] comparing peek
values not identical! 50593792 != 0
[fuzz-exec] optimization passes changed results
Expected vs actual

The original traps with memory unchanged. After --alignment-lowering the first two byte stores succeed and the third traps; the last word becomes 50593792 (0x03040000).

Version

Reproduced on upstream main at 4d8ac549e2ab9b283246ea95e79ebe139ca579ac (wasm-opt version 133).

AI was used as part of the process of finding this issue. I have manually checked and reproduced it.

主要言語
WebAssembly
スター
8.7k
フォーク
893
平均マージ
1日 11時間
マージ済み PR(30日)
74

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

WebAssembly/binaryen のほかの issue

WebAssembly/binaryen の issue をすべて見る

似ている issue

Compilers の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。