chouett0's note

掃きだめ的なsomething

Apple製品のゼロ幅非結合子処理の際に生じるクラッシュについて

初めに

つい先日、最新のものを含むiOSOS X,Watch OSに特定の文字列を送信することでクラッシュするバグが発見されました。  

gigazine.net

詳細についてはこちらを参照していただくとして、今回はこの現象を実際に検証してみた結果となります。
本来は画像を張りたかったのですがスクショを取り忘れていたので文字のみでの解説となります。
なお、今回の検証は個人の端末を用いてとなりますので第三者へ向けて行っていません。 またこの記事での内容を実際に行うと最悪の場合端末が利用できなくなる場合がありますのであくまで自己責任でお願いします。

追記: 2/21に公開されたiOS11.2.6へアップデートする事で今回のバグが修正されました

検証環境

今回の検証では
* iPhone5 iOS10.2 * iPhone6 iOS11.1.2 この2台で行い、文字列の送信・生成はPCとAndroid端末から行いました。
文字列を受信、通知させるため方法としてYahooメールアカウントを登録したiOS標準のメールクライアントとSMSにて行いました。
本来はTwitterを用いて行う予定でしたが、すでに対策がなされているようでWeb・モバイルともにバグを引き起こす文字列は送信できなくなっていました。

検証方法

まず初めにYahooメールを用いた検証について記述する前に、検証で用いる文字列について説明したいと思います。
今回問題となっている文字列は「テルグ語」と呼ばれる言語のテルグ文字という文字によるものであり、この文字を表現する際に必要な「ゼロ幅非結合子(以下ZWNJ)」という制御文と特定の組み合わせの際にのみ発火する文字のようです。
詳しい説明は

japanese.engadget.com

こちらに掲載されているので重要な部分のみを抜粋すると、今回のバグは「子音1、ヴィラーマ(発音区別符号)、子音2、ZWNJ 、母音」という組み合わせの際に発火するようです。
ということで、初めに検証のために利用したのがおそらくほとんどの記事で扱われている「U+0c1cU+0c4dU+0c1eU+200cU+0c3e」というUnicodeで表現される文字列です。当然といえば当然ですが、クラッシュを引き起こす文字列をニュース記事でそのまま記載することはまずないと思われますので、まずはこのUnicodeを実際の文字列に直していく作業です。

Unicodeから可読文字列に変換する方法はたくさんあると思われますが、私は

https://www.marbacka.net/msearch/tool.php

http://www.eva.hi-ho.ne.jp/cgi-bin/user/zxcv/decodeUTF8.cgi?req=oct&oct=343+222+242+343+202+244

この2つを用いて変換を行いました。

検証

それでは実際に検証を行う手順を記述していきます。
まずメールですが、あらかじめ検証機にメールの設定を入れておきます。
今回は標準メールクライアントを用いたので、まずはメールクライアントを開き「Yahooメール」を選択し、
メールアドレスとPWを入れて完了です。
送信する際はPCからブラウザ上で行いました。
一応件名と本文のどちらが表示されても発火するように両方に文字列を挿入しました。
両方の端末でメールクライアントを起動した状態で実際に送信してみると、正常にアプリケーションがクラッシュして再起動しました。
次に、バナーでの発火の検証をしてみるとバナーが表示される瞬間にSpringBoardがクラッシュして再起動していたことから
今回のバグの危険度がわかります。

メールソフトでの発火は確認できたので、その次にSMSを用いた検証を行いました。
この検証ではSIMを挿入したAndroid端末から同じくSIMを挿入したiPhone6にバグを引き起こす文字列を送信しました。
この検証でもメールのときと同じ結果で、アプリケーションを開いた状態ではアプリケーションがクラッシュし、バナーに表示させるとシステムがクラッシュしてしまいました。

ここまでの検証は記事にある内容の模範に過ぎず、あまり面白みはありませんでした。
そこで、私の先輩からの疑問でほかの組み合わせや少ない文字列では発火しないのかを検証してみました。
あまり長い文章だと読みにくくなってしまうので概要だけ説明すると、まず、今回の検証で用いた文字列から1文字分削った
文字列を送信してみましたが発火することはなく、次に長さは変わらずZWNJを別の場所に移して見たところやはり発火することはありませんでした。
次に、検証方法のところで記述した特定の組み合わせに従い最後の母音を別の文字に置き換えてみたところ正常に発火していました。
これらのことを踏まえると、やはり特定の組み合わせの文字列をZWNJを利用して処理する際にバグが発生していることがわかりました。

まとめ

今回の検証はただバグを引き起こす文字列を送信してクラッシュすることを確認するだけで詳しい原因やほかの組み合わせまでは調査できませんでした。
また、検証で用いた検証機が2台だけだったためそのうちより低いバージョンの端末やMac,Apple Watchでも発火するのかを検証してみたいなと思います。
ここからは完全に余談となりますが、今回メールとSMSを用いたのには理由があり本来であればTwitterを利用したかったのですが、どうやらweb・mobile両方で既に対策が行われているようで投稿はもちろん名前にすら入力できないようにされていました。
しかし、某緑のSNSアプリケーションでは対策がなされておらず、

本来検証する予定ではないプライベート機で発火してしまう事態になってしまいました。
さらに、連携させているApple Watchにも最悪の場合通知が行ってしまいクラッシュする羽目になりかけたり復旧する際に
MacBook Proで無意識にLINEを起動しようとして発火することを思い出したりと散々な思いをしたので早急にiOS11.3がリリースされることを祈ります。