Apple Silicon Macではセキュリティポリシーが導入され、サードパーティのKextはやや複雑な手段を経なければ使用できなくなりました。ユーザーから見れば複雑、デベロッパーから見ればKextを使わざるを得ないにも関わらず、イメージが悪く、難しい操作をユーザーに強いることになります。複雑な操作であるため、正しく許可されていないという状況が生まれてしまうのも致し方無い状況です。
この記事では、Kextが壊れていてロードできないのか、正しい手順で許可されていないのかを取得する方法について解説します。
Kextの読み込み要求を行う
Kextと通信ができる状態になっているかや、Kextが適切にロードされているかを調べる方法にはいくつかあります。例えば、IOUserClientを使用して実際に通信ポートを開く方法や、IOKitのレジストリを調べてロードされているか確認する方法です。
調べた結果、読み込まれていない場合には、読み込み要求を行います。読み込み要求はKextManagerの以下の2つの関数が使用可能です。
KextManagerLoadKextWithIdentifier
KextManagerLoadKextWithURL
これだけであれば簡単なのですが、どちらの関数も実行するには管理者権限が必要で、使用するための準備が大変です。
管理者権限への昇格
KextManagerの関数を実行するには次のようにします。
プログラムを管理者権限が必要な部分と、その他の不要な部分に分割します。GUIも管理者権限は不要な部分に入れます。
管理者権限が必要な部分はデーモンとして実装します。
Service Managementフレームワークのクラスや関数を使い、管理者権限の認証を行います。認証に成功したら、デーモンをシステムに登録します。登録したデーモンはスーパーユーザーで実行されます。
Service Managementフレームワークには、SMAppService
クラスとSMJobBless
関数を実装しています。macOS 13未満はSMJobBless
関数を使用します。macOS 13以降はSMAppService
クラスを使用します。
SMJobBless
関数はmacOS 13でDeprecatedに指定されました。
GUIプログラムから必要なタイミングで、デーモンに指示を出し、デーモンからKextManagerの関数を使ってKextの読み込み要求を行います。
プロセス間通信には低レベルのプロセス間通信を使用する必要があります。。SMJobBless
関数のサンプルコードではソケットを使用しています。SMAppService
クラスのサンプルコードではXPCを使用しています。
サンプルコード
SMAppService
クラスのサンプルコードは以下の場所に公開されています。デーモンではなくエージェントのサンプルですが、同様の方法でデーモンもできると思います。(筆者は未確認ですが)
SMJobBless
関数のサンプルコードは以下の場所に公開されています。
許可状態の判定
KextManagerのKextの読み込み関数の戻り値をチェックすることで、ユーザーの許可状態を判定できます。
Kextの状態 | 戻り値 | 定数 | ヘッダファイル |
---|---|---|---|
未インストール | 0xDC008001 | kOSKextReturnInternalError | OSKextLib.h |
セキュリティポリシーが「完全なセキュリティ」のため、未許可 | 0xDC00801B | kOSKextReturnSystemPolicy | OSKextLib.h |
セキュリティポリシーが「低セキュリティ」だが、未許可 | 0xDC00801B | kOSKextReturnSystemPolicy | OSKextLib.h |
セキュリティポリシーが「低セキュリティ」かつ、許可済み | 0x00000000 | kOSReturnSuccess | OSReturn.h |
それ以外のエラーについても、OSKextLib.h
に定義されています。
簡易判定で良い場合もある
ここまで書いておいて何ですが、結構大変です。簡易判定という方法もあります。例えば、次のような方法です。
状況 | 判定 |
---|---|
Kextがインストールされていない | 不正インストール |
Kextがあるが読み込まれない | ユーザーが許可していない |
この方法では、Kextが壊れていて読み込まれないや、ユーザーが自分でファイルコピーしたなどは判定できませんが、多くの場合は問題ないでしょう。
おまけの効用
Apple Silicon Macで強化されたKextのブロックですが、ちょっと不安定なところがあります。例えば、セキュリティポリシーを下げて許可してから、再び、完全セキュリティにしてから、再度、低セキュリティにするとKextが許可されないことがあります。この場合、許可ボタンも表示されません。
似たような状況で、許可する前にKextを再インストールすると、許可ボタンが消えて、再表示されないこともあります。
上記の現象は必ず再現するということではありませんが、何度か遭遇しています。
このようなときに、KextManagerの読み込み要求関数が実行されると、システムがKextの存在に気づき、許可ボタンが表示されるようになったり、ブロックダイアログが表示されたりして、システムが本来の状態に復帰します。
実装するのは大変ですが、良い面もあります。
ちなみに以下の手順でも復活することが多いです。
- Kextを削除する。
- 再起動する。
- Kextを再インストールする。
- 再起動する。