ruby-trunk-changes r52806 - r52836

今日は kosaki さんの Random の乱数生成器の Random::DEFAULT と内部的に利用しているものの分離や、安全なメモリクリアを用いるようにする修正、freeze された文字列の部分文字列取り出しの不具合修正(?)、Thread#name= の修正などがありました。

kosaki: r52806 2015-12-01 05:26:13 +0900

Random の seed 作成時に init_randomseed() でバッファに乱数を生成して seed 生成に利用してから memset(3) で クリアしていましたが、memset(3) だとその変数がその後使われていないことを検出して最適化により実際にはクリアしない、というようなことが起きることがあるようで、それを避けて確実にクリアが行われるように explicit_bzero(3) というライブラリ関数を利用するようにしています。 このため configure で explicit_bzero() および memset_s() を検出するようにしています。存在しない時は代替として missing/explicit_bzero.c が追加される予定だったようですが、このコミットには含まれていなくて追加漏れしていたようです。 memset_s() は代替実装のためみたいですね。

svn: r52807 2015-12-01 05:27:10 +0900

version.h の日付更新。

kosaki: r52808 2015-12-01 05:27:11 +0900

fill_random_bytes() に need_secure という引数を追加して、getrandom(2) で乱数生成する時に GRND_NONBLOCK を利用するかどうかを指定できるようにして、Random.new_seed では secure に、Random.raw_seed では secure でないかわりに高速に(ブロックせずに)乱数生成するようにしています。

kosaki: r52809 2015-12-01 05:27:52 +0900

include/ruby/util.h で VC++ 向けに #pragma で C4723 の警告を抑制するように指定していたのを削除しています。 r26197 で ruby_div0() の定義が削られた時にこの #pragma だけ残ってしまっていたようです。

kosaki: r52810 2015-12-01 05:29:02 +0900

拡張ライブラリ openssl の OpenSSL::Random.random_bytes および OpenSSL::PKey::DSA.new で RAND_bytes() がエラー時に -1 を返すことがあるのでエラー処理を追加しています。

kosaki: r52811 2015-12-01 05:29:22 +0900

標準添付ライブラリ securerandom の SecureRandom.gen_random で OpenSSL::Random を利用する実行での seed の生成に Random.raw_seed を利用して時刻や pid だけでなく /dev/urandom からの乱数も加えるようにしています。

kosaki: r52812 2015-12-01 05:29:37 +0900

Random の init_randomseed() で seed 生成時に使うバッファを Init_RandomSeed() のローカル変数にして init_randomseed() の引数で渡していたのを、init_randomseed() のローカル変数に移動しています。

kosaki: r52813 2015-12-01 05:30:50 +0900

configure.in で AC_CHECK_HEADERS() に複数のヘッダファイルを並べて書いていた(r40632 で1ファイルごとに改行されるようにしていました)のを、1ファイルごとに AC_CHECK_HEADERS() を呼ぶようにして、さらにファイル名の辞書順に並びかえています。

kosaki: r52814 2015-12-01 05:31:11 +0900

random.c の Init_RandomSeed() から関数 init_hashseed() と init_siphash() を切り出すリファクタリング

kosaki: r52815 2015-12-01 05:31:31 +0900

random.c の Init_RandomSeed() と Init_RandomSeed2() で Random::DEFAULT の seed と内部的に利用する hash や siphash 用に使っている乱数列の seed を使いまわしていたのをやめるようにしています。

kosaki: r52816 2015-12-01 05:32:42 +0900

random.c の Init_RandomSeed() を Init_RandomSeedCore() に、Init_Random2() を Init_Random_default() に改名して、Init_Random_default() で(これまでは InitVM_Random() でやっていた) TypedData_Wrap_Struct() で Random オブジェクトを生成して返すようにしています。

kosaki: r52817 2015-12-01 05:33:04 +0900

r52815 で追加したテストで Kernel#srand で seed を設定した時の rand が Random::DEFAULT を再現できることを確認する assertion を追加しています。

kosaki: r52818 2015-12-01 05:33:20 +0900

Thread が GVL を解放して block する処理を実施する時に割り込み用の関数 ubf(UnBlocking Function) を登録して割り込み可能な thread を管理していた signal thread list を ccan/list を使って実装するようにして、関数群を thread_list -> ubf_list と(その他も全体的に)改名しています。

normal: r52819 2015-12-01 07:53:21 +0900

r52806 でコミット漏れしていた explicit_bzero(3) の代替実装のファイル missing/explicit_bzero.c をとりあえずただの memset(3) を使って定義するようにしています。 RubyCI のエラーを修正するために置いておいたそうです。

svn: r52820 2015-12-01 07:53:50 +0900

r52819 で新規追加したファイルの svn property 設定。

kosaki: r52821 2015-12-01 09:07:21 +0900

r52806 でコミット漏れしていた missing/explicit_bzero.c を追加しています。 WindowsOS X では memset_s(3) があるのでこれを利用し、それ以外(Linux)では while ループを自前で書いてクリアするようにしています。

kosaki: r52822 2015-12-01 09:35:59 +0900

r52821 で追加した missing/explicit_bzero.c で gcc 向けに #pragma で最適化オプションを O0 に指定して最適化避けをするようにしています。また memset_s(3) の動機についてコメントに参照URLを追記しています。 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1381.pdf

nobu: r52823 2015-12-01 10:05:48 +0900

r52822 で追加した #pragma を使ったコンパイラ最適化の制御を configure でチェックして関数の attribute として付けるマクロ FUNC_UNOPTIMIZED() を定義してこれを使うように変更しています。

nobu: r52824 2015-12-01 10:24:23 +0900

include/ruby/missing.h で explicit_bzero() が memset_s() で実装されているケースで直接 inline 展開されるようにマクロを定義しています。

nobu: r52825 2015-12-01 10:25:13 +0900

parse.y のトークンのカラム位置を計算する関数 token_info_get_column() でタブの幅を想定する定数がマジックナンバー化されていたので TAB_WIDTH という定数マクロで定義するようにリファクタリングしています。

nobu: r52826 2015-12-01 10:39:24 +0900

r52824 の explicit_bzero() の代替実装の inline 化で Windows 版では SecureZeroMemory() を利用するようにマクロ定義しています。

nobu: r52827 2015-12-01 12:52:20 +0900

r52826 の explicit_bzero() の Windows での代替実装ですが、これは関数マクロ定義らしく #include を追加しています。また missing.h の inline 展開時だけでなく missing/explicit_bzero.c の代替実装でも利用するようにしています。また win32/Makefile.sub で依存関係を追加しています。

nobu: r52829 2015-12-01 13:25:06 +0900

win32/win32.c の dupfd() の引数の型を修正しています。 古い VC 対策だそうです。

nobu: r52830 2015-12-01 14:55:26 +0900

compile.c で ASN の NODE の type チェックをして rb_compile_bug() を呼び出す処理を EXPECT_NODE() や EXPECT_NODE_NONULL(), UNKNOWN_NODE() などのマクロとして定義しておいてこれを使いまわすことでメッセージの一貫性を持たせるようにしています。

nobu: r52832 2015-12-01 17:09:17 +0900

テスト用の拡張ライブラリで String オブジェクトのバッファの末尾を NUL 文字終端させないようにして文字列操作の API のテストをする ext/-test-/string/cstr.c で文字列の終端をいじる関数を切り出してメソッドとして呼べるようにして、テスト側で明示的に終端文字を書き変えるようにしています。

nobu: r52833 2015-12-01 17:13:43 +0900

rb_string_value_cstr() で freeze された文字列から部分文字列を作って終端文字に NUL 文字を置く時に例外が発生していたのを修正しているようです。 ついでに str_fill_term() で未使用になってた引数の削除や str_make_independent_expand() で termlen などを引数に追加して重複した TERMLEN() の呼び出しを抑制するようにするリファクタリングなどを行なっているようです。 またテストでは r52832 で切り出してメソッド化した終端文字書き換えを利用しています。

nobu: r52834 2015-12-01 23:14:07 +0900

Thread#name= に C の文字列として妥当な(NUL 文字を含まない) String オブジェクト以外が渡された時のことを考慮したチェック(StringValueCStr()) を追加しています。 文字列オブジェクト以外を渡すと異常終了になってたみたいですね。 [ruby-core:71774] [Bug #11756]

nobu: r52835 2015-12-01 23:36:42 +0900

r52834 の続きで、Thread#name= に nil を渡すのは許容して nil に戻すことができるようにしています。

kazu: r52836 2015-12-01 23:37:51 +0900

r52806 と r52816 の ChangeLog エントリの typo 修正。