ruby-trunk-changes r30660 - r30673

今日は alloca を利用しているところでの「長い文字列を渡すとスタックオーバフロー」という不具合が大量に修正されています。

nobu:r30660 2011-01-27 08:22:54 +0900

r30653 の dln_find_1 でファイルパスが長すぎる時の警告は fprintf() を直に使用するのでなく rb_warning() を使うようにしています。また渡されたファイル名(パス全体ではなく)だけで格納用のバッファサイズを超えているような時は探索前に警告して return NULL するようにしています。

nobu:r30661 2011-01-27 08:32:22 +0900

[ruby-core:34844] で投稿されたように、ALLOCA_N() を用いてスタック上にメモリを確保する場合、あまり長い文字列などを確保しようとするとスタックオーバフローを引き起こすのですが、ヒープから取得すると例外発生時に解放漏れの原因になります。リークしないように String オブジェクトで包んでGCされるようにするようにしないといけないので、一時バッファ用の String オブジェクトを生成/バッファ破棄する rb_alloc_tmp_buffer()/rb_free_tmp_buffer() を追加し、さらに確保するサイズがあまり大きくない場合は alloca でスタック上に確保し、大きい時だけこの一時オブジェクトを利用するマクロ ALLOCV/ALLOCV_N と解放用の ALLOCV_END を追加しています。使い方は次のコミット参照。

nobu:r30662 2011-01-27 08:41:47 +0900

proc_exec_v などで exec の引数の文字列を ALLOCA_N でスタック上に確保していたのを r30661 で導入した ALLOCV_N を利用して長い文字列は一時オブジェクトを生成して確保するようにしています。 [ruby-core:34827] [ruby-core:34833]

nobu:r30663 2011-01-27 12:46:44 +0900

r30662 で ALLOC_ARGV_WITH_STR マクロで void * にキャストされたポインタを算術演算に使用して警告/コンパイルエラーになっていたのでキャスト付きの ALLOCV_N を利用するように修正。
ちなみに gcc-4.3 では警告だけ、gcc-4.4 だと警告がエラー扱いで make がエラー終了でした。make showflags の -Werror=??? は同じだったんですけどバージョンによって少し挙動が違うんですね。

usa:r30664 2011-01-27 15:12:48 +0900

Windows 版の spawn 実装でも ALLOCV を使用して長い文字列でのスタックオーバフローを回避しようとしています。しかし ALLOCV の使い方が間違っているので短い文字列でうまく動かなそうです。

usa:r30665 2011-01-27 15:21:40 +0900

r30664 で ALLOCV の返り値(?)を受けてなかったのを受けるようにしています。 [ruby-core:34833]

kosaki:r30666 2011-01-27 18:21:40 +0900

Windows で Dir.new などのパスに長い文字列を渡すとスタックオーバフローをおこすのを修正しています。[Bug #4316] [ruby-core:34834]

kosaki:r30667 2011-01-27 18:35:56 +0900

Windows で File.identical? に長い文字列を渡すとスタックオーバフローを引き起こす不具合を修正。[Bug #4313] [ruby-core:34830]

kosaki:r30668 2011-01-27 18:50:30 +0900

Windows で Dir.open に長い文字列を渡すとスタックオーバフローを引き起こす不具合の修正その2。

kosaki:r30669 2011-01-27 20:31:48 +0900

Windows で spawn に長い文字列を渡すとスタックオーバフローを引き起こす不具合の修正その2。

kosaki:r30670 2011-01-27 21:33:57 +0900

Windows で IO.popen に長い文字列を渡すとスタックオーバフローを引き起こす不具合の修正。 [Bug #4330] [ruby-core:34898]

kosaki:r30671 2011-01-27 21:42:45 +0900

win32/win32.c で定義されている ALLOCA_N のラッパである STRNDUPA() という関数マクロはスタックオーバフローの元なので削除しています。かわりに先程導入した STRNDUPV() を使う。

kosaki:r30672 2011-01-27 21:46:30 +0900

Float() に長い文字列を渡すと……という修正のために r30645 で rb_str_tmp_new() を使って一時Stringオブジェクトでバッファを確保するようにしていたのを、ALLOCV を利用するように書き換えています。

kosaki:r30673 2011-01-27 21:58:44 +0900

Interger() など文字列から整数へ変換するメソッドに長い文字列を渡すとスタックオーバフローを引き起こす不具合の修正です。