ページへ戻る

+ Links

 印刷 

design002 :: OSASK計画

osaskwiki:design002

.bss領域のゼロクリアについて anchor.png

  • (by K, 2008.09.08)
Page Top

(0) anchor.png

  • たいていOSのアプリケーション形式には、.textセクションと.dataセクションと.bssセクションがある。このうち.bssというのは、初期値のない(=つまりどんな値であっても構わない)メモリ領域のことで、たとえばファイルI/Oのためのバッファなどのために使うのにはちょうどいい(事前にサイズが決まっているのならmallocするよりもいい、なぜならmallocをCALLするコードがいらないし、領域を確保できなかった場合のエラー処理がいらないから)。
Page Top

(1) anchor.png

  • .bssセクションというのはそういう性質のものなのに、gccの最新版はデフォルトではひどいことをする。というのは、.dataセクション内の変数うちで初期値がゼロのものを.bssに割り付けようとするのである。.bssは本来ゼロクリアすることを保証してはいないのにだ。
  • ただしこれにはもちろん理由がある。実はLinuxにしてもWindowsにしても、.bssがゼロクリアされることを保証しているのだ(MS-DOSは保証してない)。だからgccのこの方針は実害がないばかりか、.dataのセクションバイナリイメージが小さくなり、実行ファイルが小さくなる、アプリケーションのロードが速くなるというメリットがある。
  • しかしOSASKではそんなことは保証してない。OSASK-HBでも保証してない。「はりぼてOS」でも保証してない。そもそもそんなことを保証する必要がどこにあるのか。セクション本来の意味としては、ゴミデータで埋まっていていいと言っているのになんで数千、数万クロック(.bss領域の大きさによってはこれをはるかに超える)を費やしてゼロクリアするのか。そのままでいいじゃないか。OSASKやOSASK-HB、そして「はりぼてOS」でさえもtek圧縮をサポートしているので、.data内のゼロの塊やゼロ以外の一定値の連続は数バイトに圧縮されてしまうので、アプリのサイズやロード時間では負けない。むしろ格段に有利だ。
  • 実はLinuxやWindowsが本来初期化する必要のないはずの.bssをゼロクリアするようになったのには、ちゃんとした理由がある。それは、セキュリティのためだ。たとえばパスワードなどを管理するアプリが走って終了したとしよう。そうするとそのアプリが使ったメモリにはパスワードの残骸が残っているだろう。このメモリをそのまま他のアプリの.bssとして割り当ててしまったら、そしてそのアプリがいきなり自分の.bss領域を覗き込むようなアプリだったら、パスワードが見えてしまうかもしれないわけだ。これはまずい。こういうことが起こらないようにするために、LinuxやWindowsでは.bssはゼロクリアするという方針を決めたということだ。
Page Top

(2) anchor.png

  • 理由はなるほどもっともだけど、それでも.bssのゼロクリアは本質的には無駄だと思う。問題はそういう悪さを出来なくすることであって、必要も危険もないのに毎回わざわざゼロクリアすることではないはずだ。まず、ゼロクリアする必要のない場合というのが存在する。たとえば、同じタスクの別のメモリ領域がスワップアウトされて、それをそのまま渡された場合だ。これはどうせ読めるものが読めているだけになるから問題ない。
  • またたとえ元が別タスクのメモリであっても、それが.textセクションだったものであれば(市販されているコピー禁止のソフトでないかぎり)、読めても問題ない。というのは.textセクションは書き換え禁止なのでロードの時のままだし、そんな情報はわざわざ盗み見なくてもダウンロードすればいいだけなのだ。ただしマルチユーザで動いているときは、ゼロクリアする必要があるかもしれない。そうでないと、「えー誰だか知らないけどいまだにこんな古いソフト使っているやつがいるのかよ、だせー」なんていう話が起こりかねない。.bssに書いてあった情報をインターネット上に送りつけたり、ファイルに保存したりして他のユーザの見える位置におく危険もあるので、ネットワークアクセスするアプリや、タスクディレクトリ・ユーザディレクトリを越えてアクセスするアプリに対しても注意は必要だ。
  • こんなふうに、問題ある条件を絞っていけばいいと思う。またシェルの設定で、このアプリはそういういかがわしいことはしないので信用していい、というフラグをたてられるようにしてもいいだろう。さらにアプリ側から、この領域には絶対に他のタスクに見られたくない情報を含んでいるので、スワップアウトするときはゼロクリアしてくれって指定できるようにもしたい。これをちゃんと設定すれば、シェルの設定をいじってもコピー禁止の市販ソフトの.text域などを無事に守れる(まあOSを改造して、そのAPI要求を無視するようにしたら突破されちゃうんだけど、そもそもOS改造を許せばなんでも出来ちゃうし、オープンソースOSでは改造を禁止することは出来ない)。
Page Top

こめんと欄 anchor.png


Last-modified: 2009-12-21 (月) 00:00:00 (JST) (319d) by k-tan