
W^X と !W


W^X のほかにも優れたパーミッション変更機能がある。ここでは !W について説明する。
void
exit(int status)
{
        register struct atexit *p;
        register int n;

        for (p = __atexit; p; p = p->next)
                for (n = p->ind; --n >= 0;)
                        (*p->fns[n])();
        if (__cleanup)
                (*__cleanup)();
        _exit(status);
}
__atexit は、関数ポインタの *書き込み可能* リンク リストである

攻撃者がメモリ内の任意の場所を上書きできる場合、プログラムが存在すれば自身のコードを実行できる

atexit(3) の変更: 書き込み不可に設定された (関数ポインタへの) ページ リストを保持する

__cleanup は stdio によって使用される *書き込み可能* ポインタである
(stdio が使用されない場合は、リンクを回避する)
stdio が上記の atexit(3) の変更を使用するように変更

このポリシー変更を !W または "書き込み不可" と呼ぶ
この手法はその他のライブラリ コンポーネントでも使用できる
基本的に無料

