Mac

Dopamine 脱獄開発者が、謎に包まれた Spinlock タイムアウトパニック問題について語る

Dopamine 脱獄開発者が、謎に包まれた Spinlock タイムアウトパニック問題について語る

iOS 15.0~15.4.1を搭載したA12~A15デバイス用のDopamine脱獄ツールは、現時点でiPhone X以降のデバイスで利用できる唯一の最新の脱獄ツールです。とはいえ、今日の脱獄者の間で人気の選択肢となっているのも不思議ではありません。

Lars Fröder が、Dopamine 脱獄時の Spinlock タイムアウトパニックについて GitHub ページにツイートしました。

しかし、Dopamine を使っていたり、プロジェクトの開始当初からフォローしていたり​​するのであれば、プロジェクト リード開発者の Lars Fröder ( @opa334dev ) やユーザーの間で Spinlockという単語が何度も使われているのを耳にしたことがあるでしょう。

実際、Dopamineの脱獄には「Spinlock Timeout Panic」と呼ばれる既知の問題があり、最終的にはユーザーのデバイスにピンク色の画面が表示され、その後、何の理由もなく再起動してしまうという事態を引き起こします。この問題は、技術的には以下のように説明されています。

dyld_shared_cache 実行可能ページの上にマッピングすると、PPL でエッジ ケースの動作がトリガーされ、メモリ ページのスピンロックでタイムアウトが発生し、カーネル パニックが発生することがあります。

C 関数をフックする調整がインストールされ、それが挿入されるプロセスが増えるほど、この動作がトリガーされる頻度が高くなるようです。

この問題は、フックされたすべてのページをワイヤリングすることで解決できるようですが、ユーザー空間はそのようなロックを取得できず、ワイヤリングされたビットを直接反転するためにカーネル メモリ内の vm_page オブジェクトを見つけることは困難であることが判明しています。

私は Dopamine デバイスでこれらの問題を個人的に経験したことがないので、これがどのように見えるか、いつ発生するかを説明するのは困難ですが、Fröder と話して、問題の原因と考えられる点について尋ね、どのように対処しようとしているのかを詳しく知りました。

Fröder氏の回答は、私のような非技術系の人や、おそらく脱獄コミュニティの多くの人にとって非常に参考になるものであり、その後、GitHubのIssueページに公開され、一般公開されました。以下に引用する回答全文は、Fröder氏がSpinlockタイムアウトパニック問題をどのように理解していたかを示しています。

以下に、この問題について、現時点での私の理解に基づき、より深く解説してみたいと思います。ただし、これは基本的に検証不可能な仮定に基づいていることにご留意ください。

マルチスレッドシステムでは、2つのスレッドが互いに干渉するのを防ぐために「ロック」が使用されます。これにより、1つのスレッドがロックを取得し、変更を加え、ロックを解除することができます。ロックがかかっている間、別のスレッドがロックを取得しようとすると、オブジェクトが再びロック解除されるまで待機します。

スピンロックは本質的には同じものですが、パフォーマンス関連の用途に使用されます。主な違いは、スピンロックは、別のスレッドがロックを取得しようとしている間に、何かがロックの取得に時間がかかりすぎるとタイムアウトする可能性があることです。つまり、ロックを取得する際にオブジェクトが既にロックされている場合、数ティック待機し、その時間内にオブジェクトがロック解除されなければタイムアウトになります。

このメカニズム自体が問題なのではなく、メモリページに関係しています。すべてのメモリページ(16KBのRAM領域を表す)にはスピンロックが設定されているため、複数のプロセスが同時に同じページを取得しようとしても問題は発生しません。

特定のページは複数のプロセスにマッピングされる可能性があり(例えば、両方のプロセスが同じライブラリをロードする場合)、メモリを節約するために同じページが再利用されます。Tweaksはプロセスごとにこのようなメモリを上書きするため、まず既存のマッピングのプロセス固有のコピーを作成し、その上にマッピングする必要があります。これにより、例えば、あるプロセスで1つのページを変更しながら、他のプロセスでは元のページをそのまま残すことができます。この問題は、dyld_shared_cache内にあるページの上にマッピングする場合に特に発生するようです。

問題は、Appleがおそらくこの種のフックをテストしたことがなく、多数のプロセスでこれを行うと、元のページ(共有マッピングのページ)がアクティブに使用されていないためページアウトされる可能性があることです。ページアウトとは、基本的にそのページをRAMから削除し、再度アクセスされたときに再度ロードすることです。標準システムでは、フックが何も行われていないため、このようなことは起こりません。

現在、根本的な原因は、以前にページ アウトされた共有/実行可能ページをページ バックしようとしている何かであるように見えます。これにより、1 つのスレッドがスピンロックを取得し、それを取得している間に、同じスピンロックを取得する別のコンテキストにプリエンプトされるというプリエンプションの問題が発生します (プリエンプションは基本的に、1 つのスレッドが現在ビジー状態であっても他の用途に使用できるようにするメカニズムであり、常に 1 回で実行する必要があるコードがある場合は、コードで明示的に無効にしてから再度有効にする必要があります)。したがって、Apple がプリエンプションを正しく無効にしないという特定の動作からのみ呼び出される 1 つのコード パスがあるようです。これにより、1 つのスレッドが同じスピンロックを 2 回取得し、古いコンテキストがもう実行されず、スピンロックを再度ロック解除できないため、タイムアウトが発生します。

この問題を軽減するために、スピンロック関連の変数をいじってタイムアウトまでのしきい値を高くしようとしましたが、残念ながら、それに関連するものはすべて KTRR で保護されており、バイパスがないため、Apple にだまされました。適切な修正方法は、ページ アウトが決して発生せず、問題に関連するコード パスがトリガーされないように、上書きされる前にフック対象のすべてのページを「ワイヤ ダウン」(ページをワイヤ ダウンするとページ アウトが防止される) することだと思います。これまでいろいろ試しましたが、ユーザー空間からそのようなワイヤリングを取得することはまったく不可能であるため、カーネル内で実行する必要があります。残念ながら、問題の原因となるこの特定の共有マッピングに関連する構造は非常に複雑で、ワイヤリングを適用する正しいページ オブジェクトを取得する方法はまだ見つかっていません。

Spinlockタイムアウトパニック問題は、Dopamineが初めてリリースされて以来存在しており、多くの解決の試みにもかかわらず、今日まで解決されていません。とはいえ、より多くの人々がこの問題を知り、貢献できるよう対話を開くことは、より多くの人が問題と解決策についてブレインストーミングしやすくなるため、正しい前進と言えるでしょう。

フレーダー氏は、フォローアップコメントで、この問題を阻止するための次のアイデアを説明しています。

したがって、これを修正するための次のステップは、カーネル メモリ内の DSC ページの vm_page 構造を見つけることですが、これまでのところ、そのような構造を見つけようとする試みはすべて失敗しています。

まだ直接的な影響はありませんが、FröderがSpinlockタイムアウトパニックの問題を解決できるかどうかは確かに興味深いところです。この問題は、C言語の関数をフックする脱獄ツールを多くインストールするユーザーに多く発生しているようです。私のテストデバイスには、問題を引き起こすようなツールがそれほど多くインストールされていないだけかもしれませんが、世の中には私よりもはるかに多くの脱獄ツールをインストールする脱獄ユーザーが存在することは承知しています。

こちらもご覧ください: iOS 15.0-15.4.1 および iPadOS 15.0-15.4.1 を実行している A12-A15 デバイスを Dopamine で脱獄する方法

Dopamine ジェイルブレイクを使用中に、突然再起動する前にピンク色の画面が表示される「Spinlock タイムアウトパニック」に悩まされたことはありませんか? ぜひ下のコメント欄でお知らせください。

Milawo
Milawo is a contributing author, focusing on sharing the latest news and deep content.