[#44469] [Ruby 1.9 - Bug #5279][Open] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある — Shota Fukumori <sorah@...>

21 messages 2011/09/06
[#44471] [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある — Shota Fukumori <sorah@...> 2011/09/06

[#44472] Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある — "NARUSE, Yui" <naruse@...> 2011/09/06

2011年9月6日11:02 Shota Fukumori <sorah@tubusu.net>:

[#44473] Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある — "Shota Fukumori (sora_h)" <sorah@...> 2011/09/06

じゃぁ,大丈夫かな.

[#44474] Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある — Kazuhiko <kazuhiko@...> 2011/09/06

On 06/09/2011 06:10, Shota Fukumori (sora_h) wrote:

[#44541] Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある — Kazuhiko <kazuhiko@...> 2011/09/24

かずひこです。

[#44549] Re: [Ruby 1.9 - Bug #5279] $SAFEが3以上の時にString#encodeがSecurityErrorを発生させるケースがある — KOSAKI Motohiro <kosaki.motohiro@...> 2011/09/26

> かずひこです。

[#44491] [Ruby 1.9 - Feature #5314][Open] パッケージマネージャをコアリリースに含めて欲しい — Taro MURAOKA <koron.kaoriya@...>

13 messages 2011/09/13

[#44506] [Ruby 1.9 - Feature #5317][Open] rubyのヘッダファイルを使った拡張を行う際にuid_tの宣言回避をする事が出来ない。 — Yasuhiro Matsumoto <mattn.jp@...>

9 messages 2011/09/13

[#44520] [Ruby 1.9 - Bug #5350][Open] WeakRef で謎の NoMethodError — Makoto Kishimoto <redmine@...>

20 messages 2011/09/21

[#44542] [Ruby 1.9 - Bug #5363][Open] OpenSSL::ASN1.decode_all の引数に PEM 形式の証明書を指定すると Segmentation fault が発生する — Hiroshi Yoshida <hexa.diary@...>

8 messages 2011/09/25

[#44546] [Ruby 1.9 - Bug #5368][Open] ensure節でsleepするようなThreadがあるとインタプリタが終了しない — Masaki Matsushita <glass.saga@...>

22 messages 2011/09/26

[ruby-dev:44562] Re: [ruby-dev:44538] [Ruby 1.9 - Bug #5350] WeakRef で謎の NoMethodError

From: Nobuyoshi Nakada <nobu@...>
Date: 2011-09-29 11:48:38 UTC
List: ruby-dev #44562
なかだです。

At Sat, 24 Sep 2011 11:38:54 +0900,
SASADA Koichi wrote in [ruby-dev:44538]:
> (2011/09/23 19:02), SASADA Koichi wrote:
>>  うーん,これはどうするべきかな.ファイナライズ処理を遅延させるように
>> コードを書き換えれば解決できますが,ちょっと大がかりな気もしますね.問題
>> が weakref だけなら,大がかりでもいい気がしますが.
> 
>  わかりづらい文章になってしまってすみません.weakref 側を,ファイナライ
> ザ処理を遅延できるように大がかりに書き換えればよい,という意図でした.例
> えば,ファイナライザはこの処理をファイナライザの *後で* 実行するように,
> 例えば Thread 作っちゃうとかすれば解決できます.

weakrefのマップからの削除処理は、ファイナライザから遅延させてはまずいで
す。削除が完了する前にファイナライザが終了してしまうと、対象のオブジェ
クトは再利用される可能性があり、その時点でweakrefから参照すると意図しな
いオブジェクトが得られることになります。

第一の問題点は、weakrefのファイナライズ処理が再入不能なのに、ファイナラ
イザ自体は再入することがあり得ることです。[ruby-dev:44527]にある再現コー
ドのように、weakrefのファイナライズ処理で内部的に使っているMutexが外部
からも容易にアクセスできてしまうことも問題といっていいでしょう。

とりあえずファイナライザで再入しないようにするパッチです。


diff --git i/gc.c w/gc.c
index f9a945c..fad49e0 100644
--- i/gc.c
+++ w/gc.c
@@ -345,6 +345,7 @@ typedef struct rb_objspace {
 	int dont_gc;
 	int dont_lazy_sweep;
 	int during_gc;
+	rb_atomic_t finalizing;
     } flags;
     struct {
 	st_table *table;
@@ -387,6 +388,7 @@ int *ruby_initial_gc_stress_ptr = &rb_objspace.gc_stress;
 #define heaps_freed		objspace->heap.freed
 #define dont_gc 		objspace->flags.dont_gc
 #define during_gc		objspace->flags.during_gc
+#define finalizing		objspace->flags.finalizing
 #define finalizer_table 	objspace->final.table
 #define deferred_final_list	objspace->final.deferred
 #define mark_stack		objspace->markstack.buffer
@@ -2064,7 +2066,7 @@ slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
     }
     objspace->heap.final_num += final_num;
 
-    if (deferred_final_list) {
+    if (deferred_final_list && !finalizing) {
         rb_thread_t *th = GET_THREAD();
         if (th) {
             RUBY_VM_SET_FINALIZER_INTERRUPT(th);
@@ -2968,7 +2970,10 @@ finalize_deferred(rb_objspace_t *objspace)
 void
 rb_gc_finalize_deferred(void)
 {
-    finalize_deferred(&rb_objspace);
+    rb_objspace_t *objspace = &rb_objspace;
+    if (ATOMIC_SET(finalizing, 1)) return;
+    finalize_deferred(objspace);
+    ATOMIC_SET(finalizing, 0);
 }
 
 static int
@@ -3020,6 +3025,8 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
     /* run finalizers */
     gc_clear_mark_on_sweep_slots(objspace);
 
+    if (ATOMIC_SET(finalizing, 1)) return;
+
     do {
 	/* XXX: this loop will make no sense */
 	/* because mark will not be removed */
@@ -3082,6 +3089,7 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
 
     st_free_table(finalizer_table);
     finalizer_table = 0;
+    ATOMIC_SET(finalizing, 0);
 }
 
 void
@@ -3089,7 +3097,7 @@ rb_gc(void)
 {
     rb_objspace_t *objspace = &rb_objspace;
     garbage_collect(objspace);
-    finalize_deferred(objspace);
+    if (!finalizing) finalize_deferred(objspace);
     free_unused_heaps(objspace);
 }
 


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread