ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
System ExtensionとDriverKit
macOSのセキュリティと信頼性をモダナイズおよび向上させる次のステップの1つは、Kernel Extensionとドライバのためのより優れたアーキテクチャを提供することです。このセッションでは、System ExtensionとDriverKitでこの移行を実行する方法について説明します。
リソース
関連ビデオ
WWDC22
WWDC21
WWDC20
WWDC19
-
ダウンロード
(音楽)
(拍手) ジョーです サイモンと スコットも後から参加します 我々はCore OSグループの 所属です macOS 10.15 Catalinaでの Kernel Extensionを使用した― 開発について説明します
Kernel Extension またはKEXTは― ごく初期からmacOSの 一部だった技術です KEXTを使用すると 効果的で革新的な アプリケーションができ― OSの内蔵機能を拡張できます
システムを拡張する この力は― MacがMacであるために 重要な部分です
Kernel Extensionには 問題もあります
開発やデバッグが難しく―
マシンのセキュリティや プライバシーのリスクになり得ます システムの信頼性の リスクにもなります 今が更新すべき時です
MacOS Catalinaには 2つの新技術があります System Extensionと DriverKitです それらを使って アプリケーションが信頼性と― セキュリティのより高い方法で OSを拡張できます 今までより開発も簡単になります
今日の流れはこうです 最初にこれらの新技術を紹介し―
Kernel Extensionによる問題の 予防方法を説明します
サイモンがDriverKitを使用した Driver Extensionのビルド方法を
スコットが簡易USB Driverの 書き方とデバッグ方法を話します
最後にアプリケーションに 導入する方法を説明します
それでは始めましょう
System Extensionは macOS Catalinaで最初の新技術です
アプリケーションの一部で― OSの機能を拡張します Kernel Extensionに似た方法で 行いますが― カーネルではなく ユーザ空間で実行します
CatalinaでのSystem Extensionは 3種類あります Network Extensionと Driver Extension― Endpoint Security Extensionです
Network Kernel Extensionが Network Extensionに代わりました
ネットワークトラフィックの フィルタ 再ルート VPN接続をします
Network Extensionについては 金曜午前にもセッションがあります
Endpoint Security Extensionは KEXT用になりました KAUTHインターフェイスの セキュリティイベントを監視します この方法でビルドした アプリケーションには― エンドポイントの検出と応答 データ消失予防のAppがあります
Endpoint Security Extensionは セキュリティのラボに参加して下さい 1つは今 行われており もう1つは木曜の午後です
Extensionの3つ目は Driver Extensionです IOKitを使用する Device Driver KEXT用になりました
CatalinaではUSB シリアル ネットワークインターフェイスと ヒューマンインターフェイス デバイスを制御します
DriverKitでDriver Extensionを ビルドすることは― Catalinaの2つ目の新技術です DriverKitは― 新フレームワークを使用した IOKitに基づく新SDKです カーネル外のユーザ空間での― Driver Extensionのビルドを更新し 最新式にデザインしました
新技術が分かりましたね
Kernel Extensionの問題を 回避する方法に移りましょう
この場合 問題となるのは カーネル外のユーザ空間です なぜこれが問題なのでしょう
プログラム内部で カーネルは厳しい環境です
カーネルはマシンで発生することを 全て管理しています だから絶対に停止できません イベントの待機や クラッシュもできません カーネル内のコードは 機敏で予測ができ― メモリなどを使用して時間を節約し 基本的にバグのないことが必要です この制約を満たすコードを 書くのは至難の業です
System Extensionを実行するのは カーネル外のユーザ空間です つまり快適な現代の プログラミング環境で実行されます
KEXTよりも開発しやすいのは メモリの割り当てやスレッド間の 同期の場所や方法を― カーネルコードが 制限しているからです Foundationなどのシステム フレームワークは ほぼ使えません この環境で実行するように 設計されていないためです KEXTの開発でサポートされている 言語はCとC++だけです
一方 System Extensionには このような制限がありません macOS SDKのフレームワークを どれでも利用してビルドできます
Swiftを含むどの言語でも コードを書けます (拍手) 例外が1つあります ハードウェアと密接な関係がある Driver Extensionには― いくつかの制限があります DriverKitフレームワークを 使用する必要があります システムの他の部分とは 別のランタイムで実行します
Driver Extensionは― CまたはC++で書く必要があります ただしデフォルトがC++17です (拍手) System ExtensionはKernel Extensionよりデバッグが簡単です カーネルやマシン全体での カーネル停止用デバッガがあります デバッガ自身も対象です 通常デバッグには 2台目のマシンを用意して― マシンに接続する特殊なケーブルか ネットワーク設定が必要です
KEXTのビルド テスト デバッグの サイクルに時間がかかります KEXTのどんなクラッシュでも システム全体を再起動するからです
カーネルデバッガのサポートには 制限があります 表現の評価やオブジェクト値の 表示などはできません
その一方でSystem Extensionは デバッグできます
デバッグ中に カーネルは止まりません
Extensionがクラッシュしても 再起動の必要はありません ビルド テスト デバッグがデバッガ フルサポートのマシン1台でできます
Kernel Extensionと比べ System Extensionが最も向上した点は セキュリティ プライバシー 信頼性の領域です
カーネルには多くのジョブが ありますが最も重要なのは― システムのセキュリティポリシーを 定義し実施することです 各Appを切り離しハードウェアへの 直接アクセスを止めます そして セキュリティポリシーに従って― データやシステムサービスを 共有させます
ロードしたKernel Extensionは カーネルの一部になります マシンのどこでもアクセスできます これがKEXTの力のもとです しかし危険もあります
Kernel Extensionはセキュリティ ルールを作成できるため― ルールよりも上位になります
KEXTにセキュリティを 危険にさらすバグがある場合― マシン全体を乗っ取ります 開発者が意図せず ユーザが望まないことをするでしょう 防止するセキュリティルールは ありません つまりKEXTのバグは 重大なセキュリティ問題になります
KEXTのバグは…
バグは… どうしたんでしょう (笑い声) KEXTのバグで 重大な信頼性問題も発生します (拍手) 単なるカーネルクラッシュではなく パニックのため再起動が必要です このダイアログボックスは KEXTの開発者ならお馴染みですね 多くのユーザもそうでしょう
System Extensionでのピクチャの 変更点を見ましょう
System Extensionは ユーザ空間で実行されます システムセキュリティポリシーに 他のApp同様に従います 他のAppと違って特別なジョブを 実行する権限があります 例えばハードウェアデバイスに 直接アクセスしたり― カーネルシステムで直接通信する 特別なAPIを使用します
System Extensionが クラッシュしても― 残りのシステムとAppは 影響を受けず実行し続けます
これらの理由から System Extensionは― Macプラットフォームにとって 大きな1歩になります
実際に これは即座に適用を 推奨する改善点です
セバスチャンがPlatform State of the Unionで言ったように Kernel Extensionの非推奨に向けて 我々は動き出しました MacOS 10.15 Catalinaが妥協の ないフルサポートをする― 最後のリリースになるでしょう (拍手) 具体的に 機能は System Extensionで― デバイスファミリーは DriverKitでサポートされています 同じジョブへのKernel Extensionの 使用は非推奨予定です macOSの将来のリリースでは Kernel Extensionをロードしません
将来のリリースではより多くの System Extensionの種類と― DriverKitのデバイスファミリーを 追加します Kernel Extensionは 順に非推奨となります
以上がSystem Extensionの 簡単な紹介でした
ユーザ空間で実行しカーネル プログラミングを回避しています 開発とデバッグが簡単になる方法で アプリケーションが― システムを拡張できます
ユーザデータのセキュリティと 信頼性も保護します
ではサイモンと交代します 新DriverKit Runtimeを使用する Driver Extensionのビルド方法です (拍手) ありがとう ジョー
Driver Extensionは System Extensionの新タイプです ハードウェアデバイスを制御し OS全体でサービスを利用可能にします この新しいDriver Extensionを dextと言います 目的はできるだけ簡単に Kernel Extensionから― Driver Extensionに 移行することです
Driver Extensionの動作とビルド方法と KEXTからの移行方法について 4つのことを話します
最初はライフサイクルです
それと一致させて開始する方法です
KEXTと競合する程度と― 新DriverKit SDKで ビルドする方法を説明します エンタイトルメントなどの セキュリティ機能を振り返ります
最後にアプリケーションを macOS CatalinaとMojaveに― 導入する方法について 共通の疑問に答えます
ではKEXTのライフサイクルに ついてです
デバイスにDriver Extensionが ある場合に発生するプロセスです カーネルサービスを作成するIOKit Matchingを起動し表示します これはAppleが作成しました
例示するDriverKitのクラスで ドライバのプロセスを起動します
プロセスはサービスの― プロキシオブジェクトとして プロバイダなどを使います このデバイスはUSBデバイスや デバイスを… このデバイスは USBデバイスを使います カーネルデバイスの表示を呼び出す プロキシオブジェクトがあります
Kernel Extensionに DriverKitドライバを表示し― カーネルドライバと整合して 競合可能だと言うことです
IORegなどでレジストリを確認し IOKitを使えます
DriverKitドライバはカーネルから 分離されているので― 別デバイスにそれ自身のプロセスと ドライバの別インスタンスがあります
macOS Catalinaでは― AppleがDriver Extensionに ドライバを移動し始めました USBネットワークデバイスを ホストするプロセスがあり レジストリにイーサネットデバイスと して表示されます
HIDドライバなどをホストする レジストリにもプロセスがあります
DriverKit SDKを使用するDriver Extensionのビルドを説明します
KEXTのビルド経験者は簡単に Driver Extensionに移行できます 慣れているIOKit C++ APIで 開始できます
DriverKit APIはIOKit APIを ユーザ空間に拡張しました macOS SDKとは区別されている 新DriverKit SDKにまとめました
このSDKはセキュリティのため APIサーフェスが制限されます ファイルシステム ネットワーク モックに直接アクセスしません
Appleはユーザ空間のプロセスを 実行中のドライバに合わせました そして優先度を上げ 機能性を高めました
DriverKit SDKのクラスについて 説明します
IOServiceクラスはDriverKitにあり IOKitクラスにもあります
IOMemoryDescriptorとIOBuffer MemoryDescriptorも同様です
IOKitのIOWorkLoopとEventSourceは 変更されました
最後にC言語関数ポインタ表示に 必要な新クラスOSActionがあります
さらにクラスの詳細を 確認しましょう
IOServiceにStart Stop Terminateなど ライフサイクルAPIがあります
同期するには―
全IOServiceにデフォルトの DispatchQueueがあります 全メソッドが割り込み タイマー 完了などのキューを呼び出します
IODispatchQueueは実行中のGrand Central Dispatchにビルドされ― 制限されたDriverKitの環境で 実行するよう最適化されています
ドライバはキューを コントロールし― どのキューがどのメソッドを 呼び出すか決まっています
イベントAPIはIOKitのIOWorkLoop モデルと同じです ただし今はGrand Central Dispatch APIに基づいています
割り込みとタイマーにはキューと ディスパッチのソースがあります ブロックAPIはコマンドゲートに 置き換えられます
GCDは便利で馴染みのある 同期パラメータを提供します
またIOSharedDataQueue DispatchSourceもあります 共有メモリのリングバッファを 提供します 迅速さとオーバーヘッドの小さい メッセージの通過のためです
最後のクラスはOSActionです IOKit APIでコールバックされ カプセル化されます
常に非同期で― コールバッククライアントの状態を 個々に保持しています
任意の引数で定義されている コールバックができます コンパイルと実行の時に タイプを確認します
DriverKitのクラスについて いくつか説明しました 次にIOKitとは少し違うクラスの 定義方法について見てみましょう
DriverKitのインターフェイスは “.iig”拡張子で記載されます IIGというツールで 処理されています
IIGファイルはすぐに コンパイルされるクラスの定義です 一般的な型と構造をしている CとC++のヘッダをインポートします
クラスとメソッドの定義に付ける 別の属性があります 別のアドレス空間から 呼び出すために利用されます
これは基本的なクラスの定義ですが クラスでのカーネルのように特質を持ち クラスはカーネルで定義されます メソッド宣言上でローカルということは ユーザドライバで実行された メソッドです
macOS Catalina開発者プレビューで 利用できるファミリーの一部は― ネットワークインターフェイスを 生成するNetworkingDriverKit HIDデバイスを生成する HIDDriverKit
USBシリアルデバイスをOSで 利用するUSBSerialDriverKit
ドライバ内でUSBデバイスを 使わせるUSBDriverKitがあります
後でスコットが USBデバイスがサポートする― USBDriverKitなどのデモを行います
Driver Extensionを開発する セキュリティ面を説明します
いくつかのタイプの― エンタイトルメントの ドライバがあります 全Driver Extension用と― 移動エンタイトルメントという デバイス制御用です デバイスの種類によります
OSのサービスで利用するファミリー エンタイトルメントもあります
コード署名とエンタイトルメント獲得の 認証プロセスは後半で説明します
macOSの全バージョンで動作する製品に ついて簡単に述べます
macOS Catalinaと以前のリリースに 対応する製品を出すと― 古いリリースにKernel Extensionを インストールする必要がありますが System Extensionsフレームワークを 使い macOS Catalinaに Driver Extensionを提供します
ではスコットが新USBDriverKit フレームワークのデモをします ありがとう スコット (拍手)
簡易USBドライバをビルドするには 新しいUSBDriverKitフレームワークを 使って データを読み込みます DriverKit Templateを使うXcodeの 新プロジェクト作成方法について話し その後カーネルクラス対 DriverKitクラスを見ます 次にDriverKit実装の 詳細に移ります 最後に動いているドライバとLLDBで 動くdextのデバッグのデモをします
Xcodeを使用するDriverKit 新プロジェクトの作成は― Xcodeの新プロジェクトから テンプレートを選択するくらい容易です 完了するとXcodeがファイルを 自動生成して開始できます
生成されたプロジェクトには ビルド用の標準ファイルがあります Kernel Extensionで使うのはC++ エンタイトルメント info.plistです さらにXcodeはIIGファイルも 生成しています このファイルにはドライバクラスの 定義があります MyUserUSBInterfaceDriverの クラス定義を見てみましょう
見た目はカーネルドライバと ほとんど同じです パブリックIOKit Lifecycleは同じ DriverKitのStartやStopは大文字 つまり差異は小さいですが重要です
最初にDriverKitクラスでは コールバックに属性を追加します 属性でメソッドがIOUSBHostPipe オブジェクトで定義した― コールバックタイプに合わせ コンパイル時間タイプを確認します 次にDriverKitクラスで宣言される インスタンス変数はありません
初期化中に全インスタンス変数を ドライバが配置するからです MyUserUSBInterfaceDriverで 実行してみましょう
最初に全インスタンス変数を 保持するために構造を宣言します カーネルクラスのインスタンス変数を 全てこの構造に取り込みます KEXTと同じUSBカーネルタイプの ポインタがあります IOUSBHostInterfaceプロバイダや IOを実行する― IOUSBHostPipeオブジェクトなどです 非同期IOのコールバックカプセル化の OSActionオブジェクトもあります
INIT中に構造を 配置する必要があります
これがMyUserUSBInterfaceDriverの INITルーチンです KEXTと同じ方法でスーパークラスの INITを呼び出します そしてIvar構造に配置します
スーパークラスがIvarのメンバーを 定義して 配置結果の割り当てに 使う必要があります 次にStartの実装について見ます
Startでスーパークラスを呼び出し プロバイダを有効化します カーネルの方法とは少々違います
定義がマクロIMPLで 囲まれています ユーザプロセスとカーネル プロキシオブジェクトの間の― IPCをサポートするには このマクロが必要です
Super Startの呼び出しも 変更されています
USB DriverKit APIでIOUSBホスト インターフェイスプロバイダを開く―
Pipeオブジェクトを配置します
メモリディスクリプタを配置し IOで使います これはよく知られており 基本的に KEXTで実行することと同じです
この場合 非同期IOを実行して OS属性を配置し― オブジェクトがコールバックを カプセル化します
最後に残っている物が全て IOのキューに入ります
ここでセットアップが 正常にできたと仮定します 終了するとReadCompleteを呼び出す 非同期の読み込みがあります ReadCompleteメソッドが転送した バイト数とステータスを表示します 正常終了すれば 再度IOにキューイングします 次に動いているドライバを 見てみましょう
このデモでは― MyUserUSBInterfaceDriverに 追加したログを確認できます
ライフサイクルメソッドの 一部を表示します
LDBでデバッグする―
無限ループも追加します
そしてクラッシュもあります
新DriverKitフレームワークで どう復旧できるか見せます デバイスに繋いでINITを確認し KEXT内と同じように起動します ReadCompleteを呼び出し データをデバイス間で転送します PSを使用します
ドライバが実行されていることが 分かります 今は無限ループに入り LDBで ドライバ内の様子が分かります
前からあったpIDが2572の プロセスにアタッチします
ReadCompleteを 実行しているスレッドを確認します
スレッドが2つあるのが分かります
間違いなく 無限ループに入っています ユーザ空間で実行しているので ループ変数を変更できます
続ける前に詳細を確認するには― ドライバをクラッシュさせる ヌルポインタを参照します
クラッシュしたことが分かります
システムの他の部分に影響なく すぐに再起動します デバイスを外すとStopとFreeの メソッドが正常に実行されています
(拍手) それでは… (拍手) 新DriverKitフレームワークで簡単に ビルドとデバッグをしました 再びジョーがAppでのSystem Extension 配信方法を説明します
ありがとう スコット
Driver Extensionのビルド方法を 説明したので ドライバや別のSystem Extensionを 配信する方法を説明します
アプリケーションに Extensionを関連づける方法と―
Extensionバンドルのビルドと パッケージの方法です コード署名と エンタイトルメントや― System Extensionのインストール 更新 削除の方法も話します
System Extensionは常に アプリケーションの一部です これがデザインの基本原則です スタンドアロンSystem Extensionは あり得ません
アプリケーションに関しては ユーザが考えるためです ユーザがアプリケーションを購入し インストールし起動します
System Extensionを アプリケーションに実装すべきです アプリケーションがユーザと対話し Extensionを制御する方法です
アプリケーションにSystem Extensionをパッケージすると― Developer IDのあるユーザに 直接Appを配信できます 以前はできませんでしたが Mac App Store経由でもできます (拍手) アプリケーションとExtensionの 関係が近くなったため― System ExtensionがAppに関する ユーザの見分けが付きます Extensionのinfo.plistのCFBundle DisplayNameキーを使うべきです 名前をローカライズし Appの カスタムアイコンを提供します ユーザインターフェイスにも Extensionを表示すると― ユーザが利用していたAppの 一部として認識します
Extensionのinfo.plistに 使用方法も追加すべきです 何がExtensionで 何をして なぜ ユーザが起動すべきか説明します この考えはカレンダーやカメラに 必要な使用方法と同じです
Driver ExtensionではOSBundle UsageDescriptionを使用します 別のSystem Extensionでは NSSystemExtensionUsageDescription これらとAppのサポートする全言語の 文字列はローカライズされます
System Extension自身は― 実行可能でinfo.plistのあるAppの サブバンドルに分かれています info.plistはApp内にあります System Extensionを示す サンプルAppを見てみましょう Contents Library System Extensionのフォルダにあります
Driver Extensionバンドルは .dextという拡張子と― パッケージタイプ.dextを 使用します Kernel Extensionバンドルと同様に info.plistでOSBundleキーを使います
Driver Extensionは フラットバンドルで― iOSアプリケーションと同様に コンテンツフォルダがありません
別タイプのSystem Extensionは .systemの拡張子を使います CFBundlePackageTypeは SYSXつまりSystem X tensionです
XcodeでSystem Extensionは 別のターゲットです
XcodeはNetwork Extensionと内蔵 DriverKitのテンプレートを持ちます
このようなターゲットを 作る場合― Xcodeがプロジェクトの一部である Appに内蔵するか確認します 実行するとExtensionビルドの製品を コピーする― Copy Filesのフェーズを アプリケーション内に作成します
System Extensionを ビルドすると― Appで署名したのと 同じCertificateに署名します もう特別なKEXT Certificateに 署名する必要はありません
(拍手) System Extensionと主なAppの 署名でのTeam IDは一致します これがセキュリティ対策です 他の開発者のAppにExtensionを ビルドする場合があります 例えば一般的なUSBシリアル インターフェイスに― Driver Extensionが使われています その場合はSystem Extensionで 使えるエンタイトルメントがあり― 別の開発者のアプリケーションに パッケージできます
Developer IDでSystem Extensionに署名する場合― ユーザのシステムでの実行前に 認証が必要です
認証についての詳細は 昨年のセッションを見るか― 本日午後の認証についてのラボに 参加して下さい
System Extensionでは エンタイトルメントがOS機能を決めます どんなExtensionタイプで 何ができるかです 例えばDriverKit Drive Extensionでは― TransportとFamilyの エンタイトルメントを使用します
System Extensionを含む Appで使うのは― com.apple.developer.systemと extension.installの エンタイトルメントです
エンタイトルメントの詳細と 開発チームからのリクエストには― こちらのURLでご確認ください
Developer Seed of Catalina では―
ローカルな開発も行っています システム整合性保護を オフにして― コード署名とエンタイトルメントの 確認をテスト中に一部無効にします テスト終了時にオンにすることを 忘れないで下さい
アプリケーションにSystem Extensionをビルドできました どのようにユーザのシステムに インストールするのでしょう
インストーラやパッケージは 不要です System Extensionはまだ アプリケーションのバンドルです
新System Extensionsフレームワークで Appがアクティブ化を要求します Extensionをシステムで 利用するためのリクエストです システム管理者がリクエストを 承認します
ほとんどのアプリケーションでは 起動中に― アクティブ化の要求ができるので Extensionをすぐに利用できます 以前 Extensionがアクティブ化され 承認されている場合は― アクティブ化リクエストは すぐに成功で返ってきます ただしAppのライフサイクルが 違う場合があります ライセンス契約にユーザが 合意した後や― App内課金でExtensionを 要求される場合などです
Extensionが アクティブ化されると― システムが必要な時に自動的に ライフサイクルの開始を管理します ハードウェアデバイスの接続時に Driver Extensionが始まるなどです
System Extensionを更新するには Appバンドルを更新します ユーザがダウンロードして インストールするかもしれません 自動Updaterが適切にAppバンドルを 更新するかもしれません 自分でApp Storeに新バージョンを リリースする場合に更新されます
次回アプリケーションを実行し アクティブ化を要求する時には― システムがExtensionバージョンの 変更に気づきます アクティブ化リクエストのデリゲートが バージョン番号のルールに従い― バージョン番号の比較を要求します
デリゲートが 更新だと決定した場合― システムは古いSystem Extensionを止め 新しいほうで開始します
ユーザがアプリケーションを アンインストールする場合― ゴミ箱に移動し全Extensionも 自動的に非アクティブ化されます deactivationRequest APIも 使用可能ですが― 専用のアンインストーラは 不要でしょう
今日はSystem Extensionを 紹介しました Kernel Extensionに 代わる物で― アプリケーションが信頼性のある方法で システムを拡張します より安全に より開発しやすくなりました
DriverKit SDKとフレームワークの 使用方法を確認しました これらは最新式のIOKitで ドライバをビルドできます
1台のマシンでUSBドライバの例を デバッグする方法も見ました
最後にAppへのSystem Extensionの 導入方法を説明しました
ご質問がありましたら Core OSのラボでお答えします 今日の午後に1セッションと 木曜午前に1セッションあります
セキュリティのラボは今の時間帯か 木曜午後です ネットワーキングのラボは金曜午前です
ありがとう 他のセッションも楽しんで (拍手)
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。