ikemonn's blog

技術ネタをちょこちょこと

はじめて読む486 10章

OSのセキュリティ

特権レベルとスタック切り替え

  • 486は特権レベルによって、アプリケーションソフトウェアの権限を制限し、セキュリティを実現する
  • アプリケーションを実行している状態からコールゲート、割り込み、例外によってOSが呼び出されると、CPUの動作レベルは3→0になる
  • 同じタスク内で動作レベルが移行するので、アプリケーションの実行状態をそのまま引き継ぐ
  • 上記にセキュリティ上の危険がある
    • OSはまずアプリケーションから引き継いだセグメントレジスタなどの状態を保存する
    • OS自身のセグメントにアクセスできるようにセグメントレジスタの設定をする
    • 注意点:セグメントの設定前にセグメントの保存を行わねばならない
    • アプリケーションのセグメントが正しく設定されていない場合も保存しなければならない
  • これを回避するために、特権レベルの移行と連動してスタックポインタを切り替える

    • OSはアプリケーションを起動する前に、特権レベル0用のスタック領域を用意しておき、確実にアクセスできるようにする
  • 切り替えの流れ

    • CALL命令を実行する前の特権レベル3であるスタックポインタ(SS:ESP)の内容を内部レジスタに保存する
    • 特権レベル0のスタック領域のアドレスを、現在実行中のタスクのTSSから取り出し、SSとESPレジスタにロードする
    • それまで内部レジスタに保存していた旧SSとEIPレジスタの内容を切り替えたばかりのスタックにPUSHする

RPL

  • トロイの木馬などを防ぐために、486では要求者特権レベル(RPL:Requester’s Privilege Level)のチェック機能が用意されている
  • RPLはセグメントのアクセスにおいて、本来そのセグメントをアクセスしようとしたプログラムの特権レベルのこと
  • 486はセグメントのアクセスのたびに動作レベル(CPL)とセグメントの特権レベル(DPL)とを比べ、さらに要求者特権レベル(RPL)とセグメントの特権レベルを比べる
  • RPLがDPLよりも低い場合には例外を発生させる

コンフォーミングセグメント

  • OSに属する特権レベル0のセグメント内にあるプログラムを特権レベルを移行することなくアプリケーションから直接呼び出せるようにする仕組み

ローカルディスクリプタテーブル

  • 特権レベルの違いでOSのコードやデータを保護できるが、同じ特権レベル内でのセキュリティは担保されない
    • 適当にセレクタ値を指定すると偶然他のアプリのセグメントをアクセスする可能性があるので
  • アプリのセキュリティを保つために、タスクと連動した保護機能がある

参考