注目★★★★★Hacker News
GCC旧版の入れ子関数、trampolineを実行せず実行可能スタックを解除
30秒で把握
- 1Martin Uecker が旧版 GCC のnested function直接呼び出し策を提案
- 2trampolineからコードアドレスとstatic chainを抽出して呼び出し
- 3trampoline生成は残るが実行せず実行可能スタックを解除
要約
Martin Uecker は、旧版 GCC で入れ子関数をcallbackとして使う際、スタック上のtrampolineからコードアドレスとstatic chainを取り出し、関数本体を直接呼び出す回避策を提案した。GCCのtrampolineは捕捉変数を含む親関数のフレームを設定してローカル関数へジャンプするが、trampoline自体を実行しなければ実行可能スタックを再び無効化できる。実装には__builtin_call_with_static_chainとnoplateのマクロを使い、patchelf --clear-execstackでスタックの実行属性を解除する。trampoline生成は残り、間接呼び出しのdevirtualizeもできない。
あなたへの影響
旧版 GCC でnested functionを使うチームは、trampolineの命令形式と対象アーキテクチャを検証したうえで、導入前に実行可能スタック解除後のcallback動作をテストしてください。
推奨:noplateは実験的ライブラリのため、本番採用には追加検証が必要です。