AppContainer 導入による Windows 開発への影響

Windows 8 では,AppContainer と呼ばれる新たな Sandbox メカニズムが導入される.Windows ストアアプリ (旧名: Windows Metro アプリ) や,Immersive モードの Internet Explorerレンダリングプロセスなどが AppContainer で動作するプロセスの代表格だ.Windows ストアアプリ制作者にとって AppContainer が重要になるのはもちろんのこと,Windows ストアアプリ内で動作する必要のある IMEアクセシビリティ系ツールの制作者も,AppContainer について理解する必要がでてくる.

AppContainer プロセスを確認する

Process Explorer 15.23 を用いて,AppContainer プロセスの特徴を確認してみよう.以下は Windows 8 付属の「ミュージック」アプリを起動し,Process Explorer にて表示してみたところだ.
まず目に付く点として,WWAHost.exe プロセスの Integrity 欄に AppContainer と表示されていることが挙げられる.
f:id:NyaRuRu:20121008185343p:plain
次に WWAHost.exe プロセスのプロパティを表示し,Security Tab を選択してみる.プロセスのグループ一覧に,AppContainer と Capability という見慣れないグループがある.
f:id:NyaRuRu:20121008185402p:plain
前者は Windows ストアアプリごとに割り当てられるユニークな SID である.Android 環境でアプリケーションごとに User ID が割り当てられるのと似ている.後者の Capability は,この Windows ストアアプリに許可された動作と対応している.「ミュージック」アプリは,

  • インターネット接続へのアクセス
  • ミュージックライブラリへのアクセス

が許可されているようだ.
このように,AppContainer は,従来のトークン/SIDによるアクセス制御の拡張として実装されていることが分かる.例としては,Windows ストアアプリごとに SID が付与されることから,ある Windows ストアアプリにだけ,特定ディレクトリ以下へのアクセスを許すようなポリシーを設定することも可能である.

あるプロセスが AppContainer に属しているかどうかをプログラム的に判定する

あるプロセスが AppContainer に属しているかどうかをプログラム的に判定するには,プロセスのトークンハンドルに対して GetTokenInformation API を使用する.Windows 8 (SDK) 以降では TokenIsAppContainer フラグが使用でき,ここで 0 が返ってこなければプロセスは AppContainer で動作している.

あるプロセスが Immersive Mode かどうかをプログラム的に判定する

あるプロセスが没入型 UI を使用しているかどうかの判定には IsImmersiveProcess API を用いる.この用途で GetTokenInformation/TokenIsAppContainer フラグを使用するべきではない.なぜか?
それは Windows ストアアプリ風アプリケーション全てが AppContainer 内で動作するわけではないからだ.ブラウザという大きな例外がある.
Metro スタイル対応デスクトップ ブラウザーの開発」というホワイトペーパーに解説されているとおり,Windows 8 対応のブラウザには以下の 3 種類が存在する.

  1. Windows Store app: AppContainer 内で動作する
  2. Desktop browsers: Windows 7 までと同様のモデルで動作する.Win32 API にフルアクセスが可能で,JIT コンパイルや様々なマルチプロセス技術が利用可能.
  3. New experience enabled desktop browser: Windows ストアアプリ風の没入型 UI を備えつつ,Win32 API にフルアクセスが可能で,JIT コンパイルや様々なマルチプロセス技術が利用可能.

この 3 つ目が問題だ.結果として,没入型 UI かどうかの判定と AppContainer で動いているかどうかの判定は分けて考える必要がある.

AppContainer の SID を取得する

プロセスのトークンハンドルに対して GetTokenInformation API を使用する.Windows 8 (SDK) 以降では TokenAppContainerSid フラグが使用でき,ここで返ってきたものが AppContainer の SID である.

AppContainer プロセスのオブジェクト名前空間

引き続き,Process Explorer で AppContainer の動作を調べてみる.「View」→「Lower Pane View」から「Handles」を選択し,プロセス内で開かれているハンドル情報を調べてみよう.
開かれているハンドル名を見ていくと,セッション名前空間にさらに AppContainer SID が接頭辞として付加されていることに気付く.
f:id:NyaRuRu:20121008185545p:plain

\Sessions\1\AppContainerNamedObjects\S-1-15-2-43664394-2685677502-394080391-3933305958-4167273977-1510959782-2102270723\RPC Control\OLE36E12F064548B659D96055B91BF5

これに対応すると考えられる GetAppContainerNamedObjectPath API の Remarks が興味深い.この Remarks は,アクセシビリティ系など,別プロセス内で動作するツールに向けて書かれたものだ.

For assistive technology tools that work across Windows Store apps and desktop applications and have features that get loaded in the context of Windows Store apps, at times it may be necessary for the in-context feature to synchronize with the tool. Typically such synchronization is accomplished by establishing a named object in the user's session. Windows Store apps pose a challenge for this mechanism because, by default, named objects in the user's or global session are not accessible to Windows Store apps. We recommend that you update assistive technology tools to use UI Automation APIs or Magnification APIs to avoid such pitfalls. In the interim, it may be necessary to continue using named objects.

GetAppContainerNamedObjectPath

デフォルトでは Windows Store アプリからは従来の名前付きオブジェクトにアクセスできないものの,アクセス権を設定しさえすればデスクトップアプリと Windows Store アプリの間で名前付きオブジェクトを共有することが依然として可能であることが示唆されている.なお,これは暫定的な措置であり,本来は UI Automation API や拡大鏡 API を用いて対処して欲しいようだ.

All Application Packages グループを利用したアクセス制御

実は,Windows 8 では ALL APPLICATION PACKAGES と呼ばれる特殊なグループが追加されている.このグループへのアクセス許可を設定することで,Windows Store アプリに一括して動作の許可や拒否を設定することができる.
これについては,ファイルシステムの例がわかりやすい.%SystemRoot% や %ProgramFiles% のセキュリティ設定を見てみよう.Windows 8 では,デフォルトで ALL APPLICATION PACKAGES グループに対する「読み取りと実行」「フォルダーの内容の一覧表示」「読み取り」アクセスが許可されている.
f:id:NyaRuRu:20121008185631p:plain
仮に IME を開発するのであれば,仮に AppContainer 内で動作する場合であっても,ACL 的にはこれらのディレクトリ (以下) に配置された設定ファイルや辞書データは自由に読み取りできるものと考えられる.
また,試したわけではないが,AppContainer 内で動作する Windows Store アプリであっても,%ProgramFiles% 以下にインストールされたアプリケーション一覧や置かれたファイルの内容を取得することぐらいは可能なのかもしれない.これらの領域にセキュリティやプライバシーに関わるデータが置かれる場合は,悪意のある Windows Store アプリに読み取られる恐れがないか改めて確認されたい.
さて,ALL APPLICATION PACKAGES だが,ファイルオブジェクト以外にも当然利用されているようだ.
以下は,TSF が利用していると思われる Mutex オブジェクトのセキュリティ情報である.
f:id:NyaRuRu:20121008185714p:plain
ALL APPLICATION PACKAGES に同期とクエリ許可が与えられていることが分かる.このように,DACL を設定することで,Windows Store アプリとデスクトップアプリの間で名前付きオブジェクトを共有することが可能になるのだろう.
Windows Store アプリとデスクトップアプリの間のプロセス間通信についてもいずれいくつか書いてみたい.

参考