OpenSSL 1.0.2がcrashするのです
参照:OpenSSL
訳あって自宅サーバ(Mac mini G4)にOpenSSLの最新版をインストールしてみたのですが
今回は自宅サーバの Mac mini PPP-G4, MacOS X 10.4.11 Tiger に OpenSSL最新版のインスートルを試みた話。OpenSSL の現時点での最新版は OpenSSL 1.0.2c ですが、実は 1.0.2a の頃からずっとジタバタやっていたりする。
OpenSSL と言えば昨年 Heartbleed脆弱性で大騒ぎになったよね。幸いにも MacOS X ではこの脆弱性があるバージョンは使われていなかったので、慌てて最新版にアップグレードするような必要はなかったのだけど、訳あって今回 OpenSSLの最新版をインストールしてみることにしました。ビルドは成功したのですが、動かしてみると異常終了しているようで以下のようなcrashログが大量に出ていたのでした。
Host Name: Mac_mini_G4
Date/Time: 2015-06-13 10:02:44.629 +0900
OS Version: 10.4.11 (Build 8S165)
Report Version: 4
Command: openssl
Path: /Users/hoge/tmp/OpenSSL/openssl-1.0.2c/test/../apps/openssl
Parent: sh [17224]
Version: ??? (???)
PID: 17225
Thread: 0
Exception: EXC_BAD_INSTRUCTION (0x0002)
Code[0]: 0x00000002
Code[1]: 0x0020a1c0
Thread 0 Crashed:
0 libcrypto.1.0.0.dylib 0x0020a1c0 OPENSSL_ppc64_probe + 0
1 libcrypto.1.0.0.dylib 0x0020a554 OPENSSL_cpuid_setup + 196
2 libcrypto.1.0.0.dylib 0x0029e8e4 OPENSSL_add_all_algorithms_noconf + 20
3 openssl 0x00002c00 main + 384
4 openssl 0x00001dec _start + 760
5 openssl 0x00001af0 start + 48
Thread 0 crashed with PPC Thread State 64:
srr0: 0x000000000020a1c0 srr1: 0x000000000208f030 vrsave: 0x0000000000000000
cr: 0x42000242 xer: 0x0000000000000004 lr: 0x000000000020a554 ctr: 0x000000000020a1c0
r0: 0x000000000020a554 r1: 0x00000000bfffdfd0 r2: 0x000000000000004b r3: 0x0000000000000000
r4: 0x0000000000000000 r5: 0x000000000020a548 r6: 0x000000000036a824 r7: 0x00000000000000ff
r8: 0x000000000036a810 r9: 0x00000000fffff927 r10: 0x000000000000000e r11: 0x0000000084000244
r12: 0x000000000020a1c0 r13: 0x0000000000000000 r14: 0x0000000000000000 r15: 0x0000000000000000
r16: 0x0000000000000000 r17: 0x0000000000000000 r18: 0x0000000000000000 r19: 0x0000000000000000
r20: 0x0000000000000000 r21: 0x0000000000000000 r22: 0x0000000000000000 r23: 0x0000000000000006
r24: 0x0000000000072a94 r25: 0x0000000000000006 r26: 0x00000000bfffe798 r27: 0x00000000bfffe628
r28: 0x00000000bfffe628 r29: 0x00000000000518ec r30: 0x000000000036a49c r31: 0x000000000020a49c
Binary Images Description:
0x1000 - 0x6ffff openssl /Users/hoge/tmp/OpenSSL/openssl-1.0.2c/apps/openssl
0x85000 - 0xdcfff libssl.1.0.0.dylib ../util/../libssl.1.0.0.dylib
0x205000 - 0x354fff libcrypto.1.0.0.dylib ../util/../libcrypto.1.0.0.dylib
0x8fe00000 - 0x8fe52fff dyld 46.16 /usr/lib/dyld
0x90000000 - 0x901bcfff libSystem.B.dylib /usr/lib/libSystem.B.dylib
0x90214000 - 0x90219fff libmathCommon.A.dylib /usr/lib/system/libmathCommon.A.dylib
|
しかも表面上は問題なく動いているような感じで、ビルド後のテスト(make test)もpassしている様子なのですが、このテストの間にもcrashログが吐かれまくっていました。更に悪い事に、このcrashを何度も続けていると何らかのOSリソースを食い潰してしまって新しいプロセスが作れなくなるようで、何もアプリが起動できなくなったり、起動中にハングしたりするようになるみたいなのです。こうなると Macをリブートする以外に復旧手段が無いという、かなり致命的な問題。
crashログを見ると libcrypto.1.0.0.dylib の OPENSSL_ppc64_probe という所で落ちているみたいですね。gdbで動かしてみたら、
(gdb) r
Starting program: /Users/hoge/tmp/OpenSSL/openssl-1.0.2c/apps/openssl
Reading symbols for shared libraries .++ done
Program received signal EXC_BAD_INSTRUCTION, Illegal instruction/operand.
0x0020a1c0 in OPENSSL_ppc64_probe ()
(gdb) where
#0 0x0020a1c0 in OPENSSL_ppc64_probe ()
#1 0x0020a554 in OPENSSL_cpuid_setup ()
#2 0x0029e8e4 in OPENSSL_add_all_algorithms_noconf ()
#3 0x00002c00 in main ()
(gdb) disas OPENSSL_ppc64_probe
Dump of assembler code for function OPENSSL_ppc64_probe:
0x0020a1c0 : fcfid f1,f1
0x0020a1c4 : rldicl r0,r0,32,32
0x0020a1c8 : blr
0x0020a1cc : .long 0x0
0x0020a1d0 : .long 0xc1400
0x0020a1d4 : .long 0x0
0x0020a1d8 : nop
0x0020a1dc : nop
End of assembler dump.
|
やっぱり OPENSSL_ppc64_probe() に不当な命令(fcfid)があるみたいで、EXC_BAD_INSTRUCTIONという例外が起きています。EXC_BAD_INSTRUCTION例外って SIGILL のことだろう。名前に ppc64_probeとあるから、もしかして 64bit の PowerPC か検査してるのかな?fcfid命令は 64bit PowerPCアーキテクチャに(だけ?)ある命令らしいです。G4は32bitだよね。MacOS X 10.4.11 Tiger も 32bitカーネルではなかったかな?ビルドミスかなぁ?
ビルドの方法は以下のとおり。
$ tar xvzf openssl-1.0.2c.tar.gz
$ cd openssl-1.0.2c
$ ./Configure darwin-ppc-cc shared
$ make
$ make test
$ sudo make install
|
Configure に "darwin-ppc-cc" って指定しているんだけどなぁ。(64bitの場合の指定は "darwin64-ppc-cc" だと思われます。)
問題のソースプログラムは "crypto/ppccpuid.pl" という Perlスクリプトのようで、これから "crypto/ppccpuid.s" というアセンブリソースが作られるようです。"darwin-ppc-cc" 指定時には、この OPENSSL_ppc64_probe() を呼び出さないようにするか、OPENSSL_ppc64_probe() で fcfid命令は使わず無条件に 64bit PowerPCではないよという結果を返すようにしないとダメなんじゃないかな?・・・と色々と事例をググッてみたりしたのだけど、どうしても解決方法は見つかりませんでした。結局 OpenSSL の Ver.1.0系は MacOS X 10.4.11 Tiger(PowerPC G4)ではダメなんじゃないかという結論に達し、Ver.0.9.8系の最新版 OpenSSL 0.9.8zg を使って同じようにビルドしてみたら、こちらは crashすることなく動作している様子。(OpenSSL 0.9.8zg のソースには "crypto/ppccpuid.pl" は存在していません。)
と言うことで、先にインストールした Ver.1.0.2c を削除して、あらためて Ver.0.9.8zg をインストール。
$ sudo rm -rf /usr/local/ssl
$ tar xvzf openssl-0.9.8zg.tar.gz
$ cd openssl-0.9.8zg
〜以後のビルド方法は上に同じ〜
|
既存の openssl を置き換え、以下のようにシンボリックリンクを張りました。
$ cd /usr/bin
$ sudo mv openssl openssl.org
$ sudo mv c_rehash c_rehash.org
$ sudo ln -s /usr/local/ssl/bin/openssl ./openssl
$ sudo ln -s /usr/local/ssl/bin/c_rehash ./c_rehash
$ cd /usr/lib
$ sudo ln -s /usr/local/ssl/lib/libssl.0.9.8.dylib ./libssl.0.9.8.dylib
$ sudo ln -s /usr/local/ssl/lib/libssl.0.9.8.dylib ./libssl.dylib
$ sudo ln -s /usr/local/ssl/lib/libcrypto.0.9.8.dylib ./libcrypto.0.9.8.dylib
$ sudo ln -s /usr/local/ssl/lib/libcrypto.0.9.8.dylib ./libcrypto.dylib
$ cd /usr/lib/pkgconfig
$ sudo mv openssl.pc openssl.pc.org
$ sudo ln -s /usr/local/ssl/lib/pkgconfig/openssl.pc ./openssl.pc
$ sudo ln -s /usr/local/ssl/lib/pkgconfig/libssl.pc ./libssl.pc
$ sudo ln -s /usr/local/ssl/lib/pkgconfig/libcrypto.pc ./libcrypto.pc
$ cd /usr/include
$ sudo mv openssl openssl.org
$ sudo ln -s /usr/local/ssl/openssl ./openssl
|
現在はこれで様子を見ているけど、今のところcrashログが吐かれることはなく動作も問題ない様子です。
|