@@ -242,8 +242,10 @@ rb_clear_cache_by_class(klass)
242
242
}
243
243
}
244
244
245
- #define NOEX_WITH_SAFE ( n ) ((n) | ruby_safe_level << 4)
245
+ #define NOEX_TAINTED 8
246
246
#define NOEX_SAFE (n ) ((n) >> 4)
247
+ #define NOEX_WITH (n , v ) ((n) | (v) << 4)
248
+ #define NOEX_WITH_SAFE (n ) NOEX_WITH(n, ruby_safe_level)
247
249
248
250
void
249
251
rb_add_method (klass , mid , node , noex )
@@ -4468,12 +4470,16 @@ rb_call0(klass, recv, id, argc, argv, body, flags)
4468
4470
}
4469
4471
b2 = body = body -> nd_next ;
4470
4472
4471
- PUSH_VARS ();
4472
- PUSH_TAG (PROT_FUNC );
4473
4473
if (NOEX_SAFE (flags ) > ruby_safe_level ) {
4474
+ if (!(flags & NOEX_TAINTED ) && ruby_safe_level == 0 && NOEX_SAFE (flags ) > 2 ) {
4475
+ rb_raise (rb_eSecurityError , "calling insecure method: %s" ,
4476
+ rb_id2name (id ));
4477
+ }
4474
4478
safe = ruby_safe_level ;
4475
4479
ruby_safe_level = NOEX_SAFE (flags );
4476
4480
}
4481
+ PUSH_VARS ();
4482
+ PUSH_TAG (PROT_FUNC );
4477
4483
if ((state = EXEC_TAG ()) == 0 ) {
4478
4484
NODE * node = 0 ;
4479
4485
int i ;
@@ -6756,11 +6762,17 @@ method_call(argc, argv, method)
6756
6762
{
6757
6763
VALUE result ;
6758
6764
struct METHOD * data ;
6765
+ int safe ;
6759
6766
6760
6767
Data_Get_Struct (method , struct METHOD , data );
6768
+ if (OBJ_TAINTED (method )) {
6769
+ safe = NOEX_WITH (data -> safe_level , 4 )|NOEX_TAINTED ;
6770
+ }
6771
+ else {
6772
+ safe = data -> safe_level ;
6773
+ }
6761
6774
PUSH_ITER (rb_block_given_p ()?ITER_PRE :ITER_NOT );
6762
- result = rb_call0 (data -> klass ,data -> recv ,data -> id ,argc ,argv ,data -> body ,
6763
- data -> safe_level );
6775
+ result = rb_call0 (data -> klass ,data -> recv ,data -> id ,argc ,argv ,data -> body ,safe );
6764
6776
POP_ITER ();
6765
6777
return result ;
6766
6778
}
0 commit comments