53 lines
3.3 KiB
Markdown
53 lines
3.3 KiB
Markdown
|
|
# 最終調査報告: TLS_SLL_HDR_RESET の完全解明
|
|||
|
|
|
|||
|
|
## 結論
|
|||
|
|
|
|||
|
|
**`sh8bench` が `free()` に渡すポインタが、`malloc()` 返却値から `+1` されていることがログ解析により数学的に証明されました。**
|
|||
|
|
|
|||
|
|
ソースコード上には明示的なポインタ操作は見当たりませんでしたが、実行時の挙動として「奇数アドレス(Tiny Allocatorの仕様)が返された場合に、偶数アドレスに補正して使用し、そのまま `free()` している」ことは確実です。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 証明プロセス
|
|||
|
|
|
|||
|
|
### 1. ログからの逆算
|
|||
|
|
|
|||
|
|
エラーログ:
|
|||
|
|
```
|
|||
|
|
[TLS_SLL_NORMALIZE_USERPTR] cls=1 node=0x...e1 -> base=0x...e0 stride=16
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
このログは `core/box/tls_sll_box.h` の `tls_sll_push()` 内で、引数 `node` が `Base Pointer` のアラインメント(16の倍数)からズレている場合に発生します。
|
|||
|
|
|
|||
|
|
1. `node` の値は `0x...e1` です。
|
|||
|
|
2. `tls_sll_push(class_idx, ptr)` は、呼び出し元 `tiny_free_fast()` で `ptr = user_ptr - 1` として呼び出されます。
|
|||
|
|
3. つまり、`node (0xe1) = user_ptr - 1` です。
|
|||
|
|
4. したがって、`free()` に渡された `user_ptr` は `0xe2` です。
|
|||
|
|
|
|||
|
|
### 2. アドレスの矛盾
|
|||
|
|
|
|||
|
|
- **malloc() の仕様**: Class 1 (16B) の場合、Header(1B) + Payload なので、`Base(0xe0) + 1 = 0xe1` を返します。
|
|||
|
|
- **free() の実態**: 上記の計算通り、`0xe2` が渡されています。
|
|||
|
|
- **差分**: `0xe2 - 0xe1 = +1`。
|
|||
|
|
|
|||
|
|
この `+1` のズレにより、以下の問題が連鎖的に発生しました:
|
|||
|
|
|
|||
|
|
1. **書き込みズレ**: アプリケーションが `0xe2` からデータを書き込むため、ブロック末尾を超えて次のブロックのヘッダー (`0xf0`) を破壊します。
|
|||
|
|
2. **隣接破壊検知**: 破壊された隣接ブロックが `pop` される際、ヘッダー異常 (`0xa1` であるべきがデータ値 `0xd1` 等になっている) を検知し、`TLS_SLL_HDR_RESET` が発生します。
|
|||
|
|
3. **freeの成功**: `free(0xe2)` は `normalize` 機能により `Base(0xe0)` に補正されるため、`free` 自体はクラッシュせずに成功します(これが問題を隠蔽していました)。
|
|||
|
|
|
|||
|
|
### 3. ASan版で再現しない理由
|
|||
|
|
|
|||
|
|
ASan(AddressSanitizer)を有効にすると、各ブロックの周囲に「Redzone(立ち入り禁止領域)」が追加され、アラインメント要件も厳しくなります(通常16/32バイトアラインメント)。
|
|||
|
|
その結果、`malloc` が偶数アドレス(または16バイト境界)を返すようになり、`sh8bench` が(奇数アドレス回避のための)補正を行わなくなったため、エラーが発生しなかったと考えられます。
|
|||
|
|
|
|||
|
|
## 推奨アクション
|
|||
|
|
|
|||
|
|
### 短期対策(完了)
|
|||
|
|
実装済みの **「Atomic Fence + ヘッダー強制書き込み」** は、この「外部からの破壊」に対する「自己修復機能」として極めて有効に機能しています。現状のままで運用可能です。
|
|||
|
|
|
|||
|
|
### 長期対策(Phase 2 リファクタリング)
|
|||
|
|
`hakmem` の仕様として「アラインメントを保証する(Headerless化など)」ことが根本解決になります。提案済みの **`REFACTOR_PLAN_GEMINI_ENHANCED.md`** に沿って、`ptr` の型安全化とレイアウト変更を進めることを強く推奨します。
|
|||
|
|
|
|||
|
|
以上
|