Not only is the Internet dead, it's starting to smell really bad.:2014年06月分

2014/06/06(Fri)

[Hardware][Multimedia] Pioneer BDR-XS05J

時代の先端は 8k*1ちゅー時代なのに今更映画をSDとかで観たくないんですが、ThinkPad X220のUltrabaseに刺すドライブってDVDしか持ってないんですよな。

ちなヤフオクあたりで安く売ってるThinkPad用BDドライブって、あれ中古の純正DVDドライブのベゼルと固定ピンをバルクのPanasoinc UJ-262Aあたりに移植した中華製パチモン *2が100%で、ベゼルのロゴがBDじゃなくてDVDだったりします。

いちおLenovo純正で 43N3230ちゅーのが売ってはいたんですが、たかがBDドライブなのに お値段153,360円とか桁一個多い狂気の製品だった上に、Appleワナビーと化したLenovoくんはもう頭の中ゼロスピンドルでいっぱいだよぉで既に廃版です、ebayでもごくたまに出品される程度すね。

まー自分で中華製パチモンと同じ改造しようかとも思ったんですが、以前買った NASに光学ドライブが必要になる場面もあったんで、ここはポータブルドライブにすんべと去年の夏くらいに Pioneer BDR-XS05Jを買いました。

ところがですね1年経たずにUSB3.0 microB端子にクラック入って壊れましたよファッキューPioneer、 Faster/Manic Street Preachersの歌詞

 I am a pioneer, they call me primitive (俺こそが先駆者、だけど人は俺を原始人と呼ぶ)

を謹んで捧げよう、保証書どこしまったっけ(憤怒)。

ふつーこの手のポータブルドライブって中身は内蔵用のSATAドライブが入ってて、外部コネクタはSATA-USB変換が別基板で入ってることが多いです。 今回もそーゆー作りであれば修理に出すのめんどくさいので被害を最小限にすべく、ガワと壊れたSATA-USB変換は捨ててドライブだけ内蔵用に流用するんですが。

ところがなんとこの機種の中のドライブってUSB3.0 microBネイティブで、どこにもスリムラインSATA端子なぞないのよね(絶望)、 この辺参照

原始人さんは「USB3.0 microBのコネクタは弱そうに見えて挿抜耐久回数10000回ある(ドヤァ)」とか言いそうですが、そのご自慢のコネクタが基板に申し訳程度の半田リフローでくっついてたら意味無いねん。やめてくださいよ! ムカつくんじゃ! #業務を妨害する意図はありません

マジ設計者小一時間問い詰めたい。

ポータブルドライブでなく、2.5inchサイズのポータブルHDD/SSDも軒並みこのUSB3.0 microB端子採用なのですが、お願いだから標準B端子採用しちくりー。 そもそもUSB3.0 microB端子って標準B端子に比べて「薄い」だけで小さくなく「大きい」のでいろいろ本末転倒だし、ぶつけた時にも面積広いから力が分散するどころか梃子の原理で被害甚大になることが多い。

まー上下の区別がつかない端子を何年も放置し、Lightningの後追いでやっと タイプCなんて出してきたけど、これも本体の方にくるメスの端子がクッソ弱そうですぐにポキッと折れそうな設計よね *3。まじでUSBの標準化団体って製品ライフサイクルを加速させるため

というイルミナティかフリーメーソンの陰謀でこういう貧弱なデザイン設計にしてるんじゃないかと、あれこんな時間に呼び鈴が。

*1:学生時代に八景島シーパラダイスでバイトしてた頃、お土産屋にカルバンクライン「ck」ロゴそっくりの「8k」ロゴのTシャツ売ってましたが、あれさすがに今時はNGなんですかね。デザインが変わってしまった模様。
*2:まーLenovoも中華(以下略
*3:一時期のVAIO(C1 XE~XGあたりの時期)がこれによく似たメス側に細い電源コネクタ採用してて、事あるごとに折れてましたわ。

[Hardware][Networking] NETGEAR R6300-100JPS (R6300v2)

あと未だに家の無線LANが親機が54Mbpsに子機が11Mbpsなのにブチキレまして、設備更新しました。 速度より何より2.4GHzの混雑と電子レンジ干渉で使いもんになりませんわ。 ちゅーかセキュリティに未だにWEPを使ってることに(以下ry

NTT-X Storeで安かったのと某所でお薦めされたのもあって NETGEAR R6300-100JPSを今年の4月くらい?に買いました、時間限定クーポン適用で14k程度。

簡易NASとしても使えてインタフェースがUSB3.0ちゅーのがこの機種と他メーカーでは Buffalo WZR-1750DHP2しかなくて選択肢限られるのと、後者はワイが店頭回った時はまだ18kくらいしたのよね。 あと置き場所のスペースの関係でちょっとおおきすぎてはいりません(意味深)。

まぁコの業界の人ならNEC Aterm WG1800HPと合わせて3台買って蟲毒の壷するんでしょうが、わたしおかねないです *1

とりあえず使ってみた感想はまだ

くらいしかないんですが、WEB管理画面のバグいっこ気づきました。

ワイヤレスの設定で、セキュリティオプションを選択するところ。

セキュリティオプション
○ なし
○ WPA-PSK [TKIP]
● WPA2-PSK [AES]
○ WPA-PSK [TKIP] + WPA2-PSK [AES]
○ WPA/WPA2 エンタープライズ

これをGoogle Chromeから「WPA-PSK [TKIP] + WPA2-PSK [AES]」を選択して適用ボタン押しても初期値の「WPA2-PSK [AES]」に戻っちゃうのよね。

IEからだと問題ないのでそっちから設定して回避、まーjQuery使って未だにJS手書きでとかやってると以下略 *2

そういや前いた現場のネットワーク機器もNetscreenがFirefoxでないとメニューツリーが開かなかったり、ProcurveがIE以外だとAppletがまともに動かないとかあったなーと。 はやく加藤良三氏に設定画面にかうブラウザと、コンソール取るのに使うケーブルを統一して頂きたいものです。

*1:BDドライブの件も含め未だに藁人形効果が続いてるようで、こないだSONY NEX-5NとMinolta AF17-35mm/f2.8-4を落下させて修理費で数万消えたのが痛い。
*2:ちなワイはGWT推しだったんですが、流行らずJava7/Java8対応も不透明になってきて、Javaじゃなくて独自文法の方がよかったんかんかねーちゅう、haxe博士!

2014/06/07(Sat)

[Hardware][Multimedia] 続 Pioneer BDR-XS05J + Renesas μPD720200A

昨日のネタで一件書き忘れ、買った当初は Windows7 な ThinkPad X220 の USB3.0 ポートに繋いでふつーに動いてたんだけど いつの間にか「(宝くじに当たる程度に)運が良ければドライブを認識する(認識しても USB2.0 デバイスとして)」ちゅー状態になったのよね。

これもコネクタの接触が悪いんかなーとNUKISASIやってクラックを悪化させる原因になった感があるんですが、いちど別件でリカバリ戻したら まともに動くようになったので、こりゃソフトウェアやねと。

そんで原因、X220に載ってる Renesas製μPD720200AちゅーUSB3.0ホストコントローラー(コントロールできてるとはいっていない) のソフトウェア品質がクソちゅー問題でした。

つまり買ってからしばらくして Lenovo System Update で USB3.0ドライバー 2.1.36が配布された結果まともに動かなくなったちゅー感じ。ファッキュー Renesas アン Lenovo。

USBメモリなんか一般的なものは問題なく認識するので、おざなりなテストでリリースしてんだろーなと。

いつものごとく検索すると、このコントローラーの一個前の世代であるμPD720200がドライバのバージョンによって不具合が出る例がいろいろヒットします、 こ↑こ↓とか。

よくあるケースとしてNEC時代の古いドライバをRenesas時代の新しいチップ/ファームで動かしてトラブるってるんで、最新のドライバを入れてる うちの環境とは逆の話に思えたんですが、ものは試しに配信された2.1.36をアンインストールしさっきのページの2.1.27を再インストールしたら

と、まともにプラグアンプレイ(意味深)するようになりまんた。いずれにせよファームとドライバの組み合わせ問題ちゅーことですな。

後方互換、なし!w

ちなみにドライバ同梱のUSB 3.0 Host Controller Utilityから確認するとμPD720200Aのファームには4015が載ってる模様。

ファームも最新の4021(?)にアップデートすれば配信されたドライバ2.1.36(最新は2.1.39?)でも動きそうと思ったんですが、検索しても怪しいアフィ乞食転載ドライバダウソサイトばっかで まともにRenesasから再配布の権利を得てるダウンロード先が見つからないのが困りモノ、暫くは今の古いドライバで行きましょうかね。

結論、Renesas逝ってよ…あ、もう時間の問題か(ぉ グッパイSHフォーエバーSH

何はともあれ別にBDドライブがUSB3.0である必要はなかったし、USB2.0ならBDR-XS05Jの1/3の値段やねとワイそっと泣く。

2014/06/12(Thu)

[自宅システム管理者][Multimedia][Photoshop] Photomergeプラグインに於いて、レイアウトを「手動設定」で画像結合するとPhotoshopがクラッシュする

以前のどーでもいい記事 Windows XP の EOL 対応 Photoshop Elements 5 が Windows 7 未対応だったので、ワイのジャンク箱にあった 同 8のライセンスを譲ったちゅー話を書きましたが、しばらく運用した結果エンドユーザー様から「使えない」と自宅システム管理者に苦情が来たのでそのネタでも。

@Photomerge プラグインとは?

最近(といってもだいぶ前からだな)の Photoshop Elements および Creative Suite には Photomerge というプラグインがあって、複数毎の写真を繋げてパノラマ写真を作成するのを自動でやってくれたりします *1。要はそれぞれの画像同士 diff とって同じ部分を重ねてひとつの画像にするバッチ処理です。

ただし差分判定しにくい写真は所詮機械なので結合に失敗するので、その場合ユーザさんサイドがマウスでグリグリっと結合するモードもあります。 内部的には Photomerge プラグインから更に別の PhotomergeUI プラグインが呼び出されるという動作になっとるようです。

@落ちたな(確信)

ところがこの PhotomergeUI プラグインが起動すると Photoshop のウインドウタイトルが「(応答なし)」になり

Adone Photoshop CS6 は動作を停止しました

問題の解決をオンラインで確認できます。(確認できるとはいっていない)

→ オンラインで解決策を確認してプログラムを終了します(解決策があるとはいっていない)
→ プログラムを終了します m9(^Д^)プギャー

というダイアログが出て本体ごと落っこちる模様、だいじっこ!

@本家 Adobe による素晴らしい対応

本家 Adobe のフォーラムにも Photomerge プラグインが応答なしになる現象について報告があり、原因についても

  • メモリだ、メモリを増設するんだ! (富豪プログラミングはバグの元だよ派)
  • それもECCメモリだ! (宇宙線が全てのバグの原因だよ派)
  • グラボドライバとの相性問題だ、環境設定のパフォーマンスでキャッシュレベルを変更すると改善する! (ハード最適化パフォ厨プログラミングはバグの元だよ派)
  • 最新版にすれば直ってるかもしれない (お布施、とにかくお布施が重要だよカッキーン!派)

とまぁいろいろもっともらしい対策が書かれてたりしますが、どーみてもエラー報告の限りでは無関係っぽい死に方です(後述)。

この問題に長期間に渡って放置プレイだったんですが、Adobe は Photoshop Elements12 / CS5 で突如 PhotomergeUI プラグインを削除して機能ごと焼き払うという手段に出ました、これについては

  • (通常級)修正しない?
  • (比較級)修正できないのか?
  • (最上級)修正したくないのか?
  • (椎野級)修正する度胸もないのか?

椎野四段活用で野次りたくもなりますが、まぁ Adobe らしい最後といえる、クリエイティブクラウド(笑)

@Windowsエラー報告から原因を推察する

問題の例外コードを確認すると

問題の署名:
  問題イベント名:	APPCRASH
  アプリケーション名:	Photoshop.exe

  (中略)

  例外コード:	c0000005

  (後略)

すなわち EXCEPTION_ACCESS_VIOLATION(c0000005) なので考えられる原因としては

  1. 単純にバッファオーバーフローとかヌルポ参照のバグ
  2. UACとかユーザー権限に関するセキュリティ保護機能にひっかかってる
  3. DEPとかASLRのようなメモリに関するセキュリティ以下同文

ちゅーとこですな。

まずこのうち 2. と 3. でない事を確認するのに UACを無効にしたり EMETを使って DEP や ASLR を無効 *2にして試してみましたが改善しないので、もっとショボいバグなんでしょう。

@ワイ、バグの原因をほぼ特定して泣く

結論としては、PhotomergeUIプラグインのコーディングが糞でバッファオーバーランしてるみたいですな。そんでそのバッファサイズは MAX_PATH絡みでほぼ確定。

Windowsにおいて、エクスプローラーやコマンドプロンプト、PowerShellからファイルを作成する時にパスの長さはこのMAX_PATHの制限を受けます。

PS D:\> "壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍
六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍
六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍
六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍
六七八九零壱弐参四".length
244
PS D:\> mkdir 壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参
四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参
四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参
四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参
四伍六七八九零壱弐参四


    ディレクトリ: D:\


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2014/06/13      2:06            壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七
                                             八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四
                                             伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱
                                             弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八
                                             九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍
                                             六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐
                                             参四伍六七八九零壱弐参四伍六七八九零壱弐参四


PS D:\> "壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍
六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍
六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍
六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍
六七八九零壱弐参四伍".length
245

PS D:\> mkdir 壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参
四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参
四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参
四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参
四伍六七八九零壱弐参四伍
New-Item : 指定されたパス、ファイル名、またはその両方が長すぎます。完全限定型名は 260 文字未満で指定し、ディレクトリ名
は 248 未満で指定してください。
発生場所 行:38 文字:24
+         $scriptCmd = {& <<<<  $wrappedCmd -Type Directory @PSBoundParameters }
    + CategoryInfo          : WriteError: (D:\壱弐参四伍六七八九零壱弐...壱弐参四伍六七八九零壱弐参四伍:String) [New-It
em]、PathTooLongException
    + FullyQualifiedErrorId : CreateDirectoryIOError,Microsoft.PowerShell.Commands.NewItemCommand

PowerShellからmkdirを実行した時のエラーメッセージが判りやすいすね「ドライブ名を含む完全パス(完全限定型名)でUCS4で260文字制限(フォルダは更に248文字制限) *3」ですな。

ファイルのMAX_PATH(=260)文字制限、フォルダの248文字制限はそれぞれ CreateFileCreateDirectoryの Windows API の制限でありますが、今回のバグはこのMAX_PATHについて

  • 文字数=バイト数だよ
  • 文字数=ワイド文字(UCS4)数だよ

どっちなのか、解釈がわかれてしまったことによる悲劇ですね。

Windows 7のシェルはワイド文字数だとして扱うけど、Photoshop Photomergeはバイト数だと解釈してパノラマ合成したファイルを出力するパス名用のバッファに

char merged_filepath[MAX_PATH]; 

というコーディングをしてしまっとるのでしょうな。

んで、このバッファにMAX_PATH分のUCS4文字(つまりUTF-8ならMB_LEN_MAX=4ですので最大 260*4=1040byte)をガッツリ書き込んで クラッシュ、嗚呼。

@ちゅうことで回避策

エンドユーザー様には、D:ドライブ直下に作業用の短い名前のフォルダを作成し、そこにパノラマ結合したいファイルを置いて作業しろと指示しました。 これで一件落着。

@結論

これくらいすぐ原因突き止めて直してもらいたいもんだけど、機能とプラグインごと削除で対応ってAdobeの中の人たちの技術力ってどーなのよ。

ちゅーことでいつもの。

 PATH_MAX「_POSIX_PATH_MAXがやられたようだな…」

 MAXPATHLEN 「ククク…奴は我ら四天王の中でも最弱…」

 FILENAME_MAX「MAX_PATH如きに負けるとは、我らの面汚しよ…」

他にも_XOPEN_PATH_MAXとか f?pathconf(3)とかUNIXプログラミングにも強敵が大勢いるので、使い分けをちゃんと気をつけてプログラミングしようね!

@おまけ

ちなみに Cygwin の mkdir は完全パスでのMAX_PATH制限ではなく 256byte 制限やね、Windows API 関係無しに _POSIX_PATH_MAXが使われてるのだろーか。

$ echo -n 壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零\
壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零\
壱弐参四伍六七八九零壱弐参四伍 | wc -c
255

$ mkdir 壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零\
壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零\
壱弐参四伍六七八九零壱弐参四伍

$ ls
壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍

$ echo -n 壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零\
壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零\
壱弐参四伍六七八九零壱弐参四伍六 | wc -c
258

$ mkdir 壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零\
壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零\
壱弐参四伍六七八九零壱弐参四伍六
mkdir: ディレクトリ `壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六七八九零壱弐参四伍六' を作成できません: File name too long

いいのかなこれ。

*1: SONY のデジカメだと スイングパノラマで撮影した時点で勝手に繋いでくれるんだけどねー
*2:ちな ASLR を無効にすると IE10 以降は起動しなくなるので注意。さらにその状態で IE の再インストールをしようもんなら %windir%\servicing\Packages 以下の整合性がぶっ壊れ、悪名高い WindowsUpdate 9C59 エラーになるので注意、pkgmgrで手動で競合するパッケージをアンインストールする羽目になります。
*3:この260/248文字制限はAPIの制限であって、NTFSそのものはパス名の上限は約32,000文字まで許容しとります。

2014/06/26(Thu)

[Citrus][FreeBSD][Security] FreeBSD-SA-14:15およびCVE-2014-3951 について(その1)

@重要なお知らせ

えーとCitrus iconvについて FreeBSD-SA-14:15なるものが出ています、より一般的には CVE-2014-3951の番号が割り当てられるYoですが、こっちは未だ未公開(馬に乗馬)かな?

@影響範囲

最も最悪(馬に乗馬)のケースとしては「リモートからのサービス拒否」攻撃が成立します。 これがツンデレ妹からのサービス拒否であればMッ気ムンムンのやきうのお兄ちゃん彡(゚)(゚)絶頂なんですが、まぁさっさと対策してどうぞ。

にぃに…にぃに…んちゅ…んちゅ…

今日時点でCitrus iconvを導入しているOSは現状

  • NetBSD (=Citrus本家)
  • FreeBSD
  • DragonFlyBSD

の3つのはず *1ですが、問題が発生するのはFreeBSDとDragonFlyBSDだけで NetBSD (=Citrus本家)には影響はありません*2これ重要なのでふっといふっとい字にしておきました、詳しい話はまた後で後述、馬に乗馬。

@発生しうる条件

文字コード変換をiconv(3)ないしiconv(1)に投げてるアプリとかスクリプトは全て影響受けます、最近は多いよね。

UTF-8とUCS4の相互変換だけに限定利用してるとかなら今回の問題には影響ないのですが、攻撃者が以下のいずれかの文字コードを選択可能だとダメっす。

  • Big5-2003, Big5-E, Big5-Eten, Big5-IBM, Big5-Plus, CP950(台湾)
  • Big5-HKSCS(香港)
  • HZ, HZ8(中国)
  • VIQR(ベトナム)

ユーザ入力を制限してなければこれのうちどれか選ぶだけでアウトだし、絞ってたとしても台湾と香港のBig5系はデファクトスタンダードなのでまずダメでしょう。影響範囲大きいと思います。

お使いのFreeBSD/DragonFlyBSDに問題が有るか無いかの確認はiconv(1)で簡単に試験を試みられるれろなのでやってみませう。

$ echo "opie vuln vuln" | iconv -f CP950 -t UTF-8
Segmentation fault (core dumped)

$ echo "opie vuln vuln" | iconv -f HZ -t UTF-8
Segmentation fault (core dumped)

$ echo "opie vuln vuln" | iconv -f VIQR -t UTF-8
Bus error (core dumped)

ひえっ、ちなこの結果はFreeBSD 10-RELEASE。オフコースもちろんNetBSDでは問題ありません。

@バタフライ効果による熱い風評被害を受けるアプリケーション達

影響を受けそうなサービス系のアプリとしては、脆弱性の西の横綱、 BINDのidnkitがiconv(3)使って国際化ドメイン名変換やってるようね。 idnalias.confにBig5とかあるし影響不可避っぽいです。

東の横綱 Apache HTTP ServerAPR(Apache Portable Runtime)で自前の文字コード変換 *3を抱えてるので大丈夫なはず、native iconv使うオプションあったっけ?

それと東前頭の SambaもUSE_NATIVE_ICONVだとmount_cifsのオプションでcodepageにCP950を指定したりするとダメそう。

また DovecotCourie-IMAPみたいなMDAに対して問題の起きる文字コードなメール投げるだけで気軽にリモートDoSできる可能性があります。

あと libxmlもiconv依存だし GNOMEあたりのアプリも軒並みクラッシュさせられそうやね、よう知らんけど(大阪人)。

わあい(白目)。

それ以外にも、昨今はgettext(3)みたいなメッセージカタログ機能もiconv(3)を内部的に使っとります *4。なんでlibintlをリンクしていればLANG環境変数を汚染することで攻撃可能ですやね。 ウェプアプリケーションフレームワークなんかも p5-Locale-gettextPHP-gettextあたりでUIの国際化をしてた場合、Big5系を選ぶとmod_perlとかphp-apc/fpmあたり巻き込んで死にそう *5

やっぱりdjb先生みたいにlibcなんか信用できるかksgが正義なんですかね(ぉ

@ワイ、責任を取ってharakiriするべきか調査開始。

こんな影響範囲の広いCVE出すような脆弱性を出した場合「これは harakiriやろうなぁ」とCitrusの偉い人も仰せになられておりますので。

SA番号が14と15の二つが割り当てられてることからとおり、問題は2つありますので次回はそれぞれについて解説しなぜNetBSDでは発生しなかったのかを解説する予定 *6

*1:めんどいので確認してないけどMacOS X/Darwin、Minux3、QNXあたりも微レ存、でも俺は嫌な思いはしてないから。
*2:だけどspz氏がこのFreeBSDでの patchをあたるところだけ(rejは無視して) commitしてくれやがってるので、NのSecurity Officerが検証せずにNetBSD-SAを出す可能性もあるけどね、タノシミダナー(棒)。
*3:最近はそれを使ってiconvをエミュレートするAPR iconvというものも出してるし。
*4:本来のCSI思想なら無用なんですがUnicode Hardwire野郎共の時代だししゃーない
*5:まぁ今時この手のウェブアプリでUTF-8以外使ってるようなところはなさそうだけども。
*6:すでにtwitterではネタばらし済ですがまー誰もあんなチラシの裏以下の下水垂れ流し読んでないだろう。

2014/06/27(Fri)

[Citrus][FreeBSD][Security] FreeBSD-SA-14:15およびCVE-2014-3951 について (その2)

昨日の続きです。

@citrus_prop パーサにおける NULL pointer dereference 問題

FreeBSD-SA-14がこれに相当します、II. Problem Description における以下の部分です。

A NULL pointer dereference in the initialization code of the HZ module

この文章だと libHZ( citrus_hz.c)側の問題っぽいですが、実際にはこれ citrus_prop パーサ( citrus_prop.c)のバグですやね。 なのでこいつを使ってる libBIG5( citrus_big5.c) にも同様の脆弱性があります。

最初にこの文言と対策patchを見たときに、明示的に NULL を渡さない限りありえねーし必要なところには契約プログラミング *1で NULL はこないと 表明しとんのにと思いました。

以下、実際の「the initialization code of the HZ module」の コードです。

694 static int
695 _citrus_HZ_encoding_module_init(_HZEncodingInfo * __restrict ei,
696 	const void * __restrict var, size_t lenvar)
697 {
698 	int errnum;
699 
700 	_DIAGASSERT(ei != NULL);
...
705 	errnum = _citrus_prop_parse_variable(
706 	    root_hints, (void *)ei, var, lenvar);

700行目の_DIAGASSERTマクロで_HZEncodingInfo 型のポインタ ei が NULL で無いと表明しています。

ちなどーでもいいですが _HZEncodingInfo 型というのは↓こんなん。

121 typedef struct {
122 	escape_list e0, e1;
123 	graphic_t *ascii, *gb2312;
124 } _HZEncodingInfo;

前回 影響範囲で触れたように libHZ は HZ と HZ8 という2種類の符号化文字手法を扱うのですが、それぞれで振る舞いが変わる部分の情報については この型に閉包されます(要はクロージャっす)。

そんで iconv_open(3) や setlocale(3) が呼ばれると、このクロージャが先ほどの _citrus_HZ_encoding_module_init() 内で初期されます。 初期化に必要なパラメータは、引数である

  • var (バイト列)
  • lenvar (バイト列長)

がそれ。このパラメータって実体はただの文字列で LC_CTYPE database や iconv database の中で定義されてる VARIABLE ちゅーものです。

mklocale(1)のマニュアルに

     VARIABLE   This keyword must be followed by a single tab or space charac-
                ter, after which encoding specific data is placed.  Currently
                only the EUC encoding requires variable data.

と説明ありますな *2

この文字列なんですが、これまで各モジュールがてんでバラバラにパーサを実装していました。 ですがサポートする符号化文字集合が増えるにつれ、必要なパラメータも増えて手間がかかるようになったので、 ワイが libHZ を実装したときに citrus_prop という共通パーサを実装を追加したのですよな。 モジュール側で実装しなくても、hint と callback function だけマクロ使って定義しとけば良くなるので、ほんのちょっと開発が楽になるような気がします *3

こいつを利用してるのが libHZ とlibBIG5 の2つのモジュールなので、今回の NULL pointer dereference 問題はこの2つでのみ発生してる事と完全に一致。 作者であるワイにはすぐに citrus_prop パーサの不具合(あっ、察し)となるわけです。

ここまで整理すると

  • クロージャはわざわざ表明して NULL にならないことを保証している
  • パラメータも LC_CTYPE/iconv database にちゃんと定義されてるので NULL にならないことは確実
  • 問題が発生してるのは citrus_prop パーサ内部

うーんこの、どう考えても NULL pointer dereference が発生する要素が微粒子レベルでも存在しません、ワイ混乱。

@俺達はとんでもない思い違いをしていたようだ。

話は聞かせてもらった、地球は滅亡する(キバヤシAA略)

これ( iconv.patch)を見てみろ。

まず citrus_prop の関数及びコールバック関数のプロトタイプで引数の void ** を void * に変更している、これはノイズと考えられるので削除し、残りの差分を取り出す。

Index: libc/iconv/citrus_prop.c
===================================================================
--- libc/iconv/citrus_prop.c	(revision 267897)
+++ libc/iconv/citrus_prop.c	(working copy)
@@ -436,7 +436,7 @@
 			break;
 		_memstream_ungetc(&ms, ch);
 		errnum = _citrus_prop_parse_element(
-		    &ms, hints, (void ** __restrict)context);
+		    &ms, hints, (void ** __restrict)&context);
 		if (errnum != 0)
 			return (errnum);
 	}
Index: libiconv_modules/BIG5/citrus_big5.c
===================================================================
--- libiconv_modules/BIG5/citrus_big5.c	(revision 267897)
+++ libiconv_modules/BIG5/citrus_big5.c	(working copy)
@@ -179,7 +179,7 @@
 
 	if (start > 0xFF || end > 0xFF)
 		return (EINVAL);
-	ei = (_BIG5EncodingInfo *)ctx;
+	ei = (_BIG5EncodingInfo *)*ctx;
 	i = strcmp("row", s) ? 1 : 0;
 	i = 1 << i;
 	for (n = start; n <= end; ++n)
@@ -197,7 +197,7 @@
 
 	if (start > 0xFFFF || end > 0xFFFF)
 		return (EINVAL);
-	ei = (_BIG5EncodingInfo *)ctx;
+	ei = (_BIG5EncodingInfo *)*ctx;
 	exclude = TAILQ_LAST(&ei->excludes, _BIG5ExcludeList);
 	if (exclude != NULL && (wint_t)start <= exclude->end)
 		return (EINVAL);

するとできあがる差分……『ノ ス ト ラ ダ ム ス』。

つまりこのバグの本質は NULL pointer dereference なんかではなく

NetBSD から FreeBSD へ移植された時に作業者が & や * を誤って消してしまった後テストしてなくて発覚しなかった

だったんだよ!

(; ・`д・´) ナ、ナンダッテー !! (`・д´・ (`・д´・ ;)

そりゃーNetBSDで問題が発生するわけありませんわ、FreeBSD-SA-14についてワイは完全無罪の勝訴判決ガッツポーズ淫夢くん。

@次回予告

残りの FreeBSD-SA-15 も調査します、みとけよ~みとけよ~。

*1:NetBSD では 契約プログラミングが推奨されとりまして、関数の引数についての事前条件はすべて_DIAGASSERTマクロで違反が無いかをチェックしています
*2:the typical NetBSD style、内容が古いのでlibEUCでしか使ってないような事書いてありますが、今は使ってないのはlibUTF8くらいじゃなかろうか。
*3:今考えると hint とか定義すんのクッソめんどいし実装ウンコやね。前からもっとマシなものに書き直したかったんだけど後方互換の壁があってだな。 ちな正月くらいに新しいプロパティ機構実装してテストケース書くのめんどくさくて放置中、そのうち bitbacket の Portable Citrus iconv に入ります。 こっちは後方互換とか全部捨てていくスタイルなので。

2014/06/29(Sun)

[Citrus][FreeBSD][Security] FreeBSD-SA-14:15およびCVE-2014-3951 について (その3)

前回の続きです。

一転攻勢一点訂正、FreeBSD-SA-14:15 って14と15連番の Security Advisary の意味じゃなくて、2014年の15番目の意味なのね… まぁ俺西暦2114年まで生きてないから困らんしどーでもいいけど。

@citrus_viqr モジュールにおける Out Of Array Index Bounds 問題

これは II. Problem Description における以下の部分です。

an out of bounds array access in the initialization code of the VIQR module

libVIQR( citrus_viqr.c)の問題で、配列にその長を超えた添字でアクセス発生しとるちゅー指摘です。

最初にこの文言と対策 patch を見たとき(おっ off-by-oneか?)とおもいまんた。 どれだけ気をつけて実装してもチョロリとはみ出すのは、皆さん日常生活でも鼻毛、ズボンからシャツの裾、チャックから陰茎とか良くあることです(ボロリ)。

ところが実際に FreeBSD をクラッシュさせてみると Bus Error 起こしてるのでちょっと普通じゃないのですな

$ echo "Any *.exe that crash is a VC, Anyone that stands still is a well disciplined VC6." | iconv -f VIQR -t UTF-8
Bus error (core dumped)

普通 off-by-one 程度ならクラッシュする原因は Stack Smashing Protection によるバッファオーバーラン絶対殺すマンか Segmention Fault 程度の致命傷で済むわけですが。

あとは 新井が悪いアライメント問題?そんなの気にするコード書いた覚えないしのう、サクラメント中島ならスターの球団でショート守ってくれてええんやで?年俸次第だけど。

考えても理由わからんので、今回の Security Advisary によるコードの修正箇所を当バグにおいてのみ抜き出してみましょう。

Index: lib/libiconv_modules/VIQR/citrus_viqr.c
===================================================================
--- lib/libiconv_modules/VIQR/citrus_viqr.c	(revision 267591)
+++ lib/libiconv_modules/VIQR/citrus_viqr.c	(working copy)
@@ -431,7 +431,6 @@ static int
 _citrus_VIQR_encoding_module_init(_VIQREncodingInfo * __restrict ei,
     const void * __restrict var __unused, size_t lenvar __unused)
 {
-	const mnemonic_def_t *p;
 	const char *s;
 	size_t i, n;
 	int errnum;
@@ -455,7 +454,10 @@ _citrus_VIQR_encoding_module_init(_VIQREncodingInf
 			return (errnum);
 		}
 	}
-	for (i = 0;; ++i) {
+	/* a + 1 < b + 1 here to silence gcc warning about unsigned < 0. */
+	for (i = 0; i + 1 < mnemonic_ext_size + 1; ++i) {
+		const mnemonic_def_t *p;
+
 		p = &mnemonic_ext[i];
 		n = strlen(p->name);
 		if (ei->mb_cur_max < n)

変更前は、for(i = 0;; ++i) で無限ループだった部分を、for (i = 0; i + 1 < mnemonic_ext_size + 1; ++i) に変更してます。

ファッ!? 俺は無限ループするコードなんぞ書いた覚えないってば、どういうこと!?(驚愕)

@そもそも VIRQ って何?

まずワイの書いたコードを理解するため寄り道、VIRQ(=VIetnamese Quoted Readable)ってのはかつてベトナムで利用されていた文字コードです、 RFC1456になってます。

ヴィカーと発音するけど、モリッシーの巻き舌とはたぶん無関係、 デュルルヴィカーインチュッチュー

実際には文字コードちゅうか、7bitなUS-ASCIIの文字のみを使ってラテン文字の ダイアクリティカルマークをニーモニックで表現する 翻字ですやね *1。古のUsenet時代の非8bit clean環境における遺物(日本におけるISO-2022-JP的存在)ですが、今でも情報交換用としてではなく TelexVNIと共にベトナム語入力メソッド用として生き残ってます。

かつてベトナム語の記述には漢字と チュノムという文字が使われていましたが、フランスによる植民地支配の結果 クオック・グーと呼ばれる方法でラテン文字でベトナム語を記述するようになった結果ですな。 *2

日本でも某巨大匿名掲示板や某動画サイトで、某やきう選手の名前がアルファベットに翻字される例がみられますが、たった一度の過ちを深く追求してはいけない(戒め)。

ちょww角川書店がKADOKAWAに!?ww

@VIQRのニーモニックには多くの変種があり、実用上 RFC1456 では十分でない

これは RFC1456 が VISCII との変換のみ定義してることによる問題。 ワイが libVIRQ の実装した頃にはまだインターネット上で VIQR の変換サービスを提供してるサイトがあったんですが、どこも RFC1456 以外にもニーモニック定義してるようです。 ですがドキュメント化されてないので、ワイ仕様が無いから実装できません状態に。

なもんで現地ベトナムの人が必要であれば、後から拡張ニーモニックを追加できるよう、 拡張性を持たせたコードにしたわけです。

 94 typedef struct {
 95 	const char *name;
 96 	wchar_t value;
 97 } mnemonic_def_t;
 98 
 99 static const mnemonic_def_t mnemonic_ext[] = {
100 /* add extra mnemonic here (should be sorted by wchar_t order). */
101 };
102 static const size_t mnemonic_ext_size =
103 	sizeof(mnemonic_ext) / sizeof(mnemonic_def_t);
...

524 	for (i = 0; i < mnemonic_ext_size; ++i) {
525 		p = &mnemonic_ext[i];
526 		_DIAGASSERT(p != NULL && p->name != NULL);
527 		n = strlen(p->name);
528 		_DIAGASSERT(n <= MB_LEN_MAX);
529 		if (ei->mb_cur_max < n)
530 			ei->mb_cur_max = n;
531 		errnum = mnemonic_append_child(ei->mroot,
532 		    p->name, p->value, ei->invalid);
533 		if (errnum != 0) {
534 			_citrus_VIQR_encoding_module_uninit(ei);
535 			return errnum;
536 		}
537 	}
538 

RFC1456 で足りないニーモニックが後に明文化されれば、mnemonic_ext配列に随時追加していけばいいという親切設計。

親切といってもl10nの原則「余計な親切心を持ち込まない」の精神で、どのニーモニックを追加するかは現地ベトナムの人に丸投げしてます。 罷り間違っても アイルランドのアレのような自分勝手は NG ちゅうことで。

@話を戻して、問題のコードに注目

んでんで 524行目に注目、ちゃんとワイの書いたコードは無限ループではなく i < mnemonic_ext_size という条件になってます。

つまり今回の Out Of Array Index Bounds を引き起こした無限ループは、FreeBSDへのCitrus iconv移植の際に元のコードの意図を無視して勝手に削られたちゅうことです。

ば~~~っかじゃねえの!?(AA略)

@なぜ FreeBSD は愚かにもループ終了条件を削ってしまったのか?

すでに Citrus iconv のツリーへの インポート時点でこの脆弱性は 存在するので、誰のやらかしかは判りません。

ですがこの脆弱性報告者による 最初の修正、そしてその後の 一連のcommit logをみると

102 static const size_t mnemonic_ext_size =
103 	sizeof(mnemonic_ext) / sizeof(mnemonic_def_t);

が、mnemonic_extにニーモニックが1つも定義されてない現状だと、mnemonic_ext_sizeはコンパイル時にゼロになるから

524 	for (i = 0; i < mnemonic_ext_size; ++i) {

は gcc のバージョン問題なのか最適化オプションなのかバグなのか知らんけど

for (i = 0; i < 0; ++i)

と解釈されてしまった結果

-Wtype-limits
	Warn if a comparison is always true or always false due to the limited range of the data type,
	but do not warn for constant expressions. For example, warn if an unsigned variable is compared against zero with ‘<’ or ‘>=’.
	This warning is also enabled by -Wextra. 

の警告に引っかかったちゅー感じ?ちな手元のgcc 4.5.3と4.8.3では問題なさそうなんだけど。

よく考えたらFはもうclangだっけ、そっちだと-Wtype-limitsではなくて-Wtautological-compareだけども、これだって定数マクロじゃないんだし警告出るのがおかしい。 というか手元でいくら試しても再現しないんだが、これamd64以外の環境でのclangバグじゃない?(適当)

まぁ細けぇことはいいんだよ、要するにFreeBSDでこの作業やってた連中は

  • 警告が出たコードのビルドを通すため
  • 中身も読まずに終了条件を消すという愚かな行為をやらかして
  • 無限ループによる Out Of Array Index Bounds で脆弱性を引き起こした
  • その上ろくすっぽ原因を検証してないので、修正patchで「i + 1 < mnemonic_ext_size + 1」みたいないずれoff-by-oneやらかしそうなコードを平気で出してくる

つまりは極めつけのアホということです。もしかして サルによるコーディングかな?

@次回予告

めんどくさいから放置するかもしれないけど、前回今回みたいな馬鹿げたバグを出さないためにlibc開発者はどうすべきかを書く予定。

*1:同様の翻字の例としては、チベット文字をローマ字転写する ワイリー法とかあります。
*2:国際政治( 落合信彦感)による文字強制としては、モンゴル人民共和国がソ連による支援で独立した後にモンゴル文字を捨ててラテン文字→後にキリル文字での記法に移行してますな。