脆弱性

2009年07月23日

CNET Japan : Linuxの脆弱性を突くゼロデイエクスプロイトが公開に

Linux Kernel の脆弱性により、見慣れない GCC のコンパイルオプションが話題になっています。恥かしながら、私は今回の一件で始めて知りました。GCC の online manual を見る限り、少なくとも GCC 3.0.4 からは存在するオプションのようです。

GCC Manual 3.10 Options That Control Optimization -fdelete-null-pointer-checks

マニュアルの説明を読むと、既に一回ポインタを間接参照した後の NULL チェックは無意味だから削除するという、何の問題も無い最適化に見えます。

GCC 4.4.1 までは -O2,-O3,-Os で有効になっていたようですが、最新のマニュアルでは(一部のターゲットを除き)全ての最適化レベル(-O0 含む)で有効になると書いてあります。

このリンク元のブログ記事のコード
struct sock *sk = tun->sk;  // initialize sk with tun->sk

if (!tun)
return POLLERR; // if tun is NULL return error
を一見した時、何が問題なのかよくわからなかった (NULL チェックがあろうがなかろうが、NULL ポインタを参照した瞬間に SEGV が発生して kernel panic になるはず、と思った) のですが、kosaki さんの記事を読んで納得。

革命の日々 : 「Linux カーネルの zero-day exploit コード、リリースされる」への余談

Linux Kernel では、ユーザプロセスが 0 番地に mmap を実行することが可能なので、

(1) 0 番地を間接参照しても SEGV が発生しないようにできる。
(2) NULL チェックが GCC の最適化によって削除されてしまっている。
(3) Kernel が 0 番地にアクセスしてしまう。(任意のコードを実行させることができる。)

というメカニズムのようです。なるほど。

私は、これは GCC の問題というよりは、ポインタを NULL チェック無しでいきなり参照している Linux Kernel のコードの問題だと思います。しかし、Kernel などのセキュリティが重要なソフトウェアをビルドする際には、fno-delete-null-pointer-checks を付けておいた方が良さそうです。

# あるいは、NULL チェックが行われていないポインタ参照全てにデフォルトのチェックコードを挿入するようなオプションがあれば良いのかもしれません。

記事検索
最新コメント
「最新トラックバック」は提供を終了しました。
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード