On Wed, Aug 23, 2006 at 02:13:46PM +0900, Yukihiro Matsumoto wrote:
> Hi,
> 
> In message "Re: sandbox timers & block scopes"
>     on Wed, 23 Aug 2006 01:56:15 +0900, why the lucky stiff <ruby-core / whytheluckystiff.net> writes:
> 
> |From rb_rescue:
> |
> |  if (!rb_obj_is_kind_of(argv[0], rb_cModule)) {
> |      rb_raise(rb_eTypeError, "class or module required for rescue clause");
> |  }
> |
> |There is a very nice side effect of this code.  rb_eException is derived from
> |rb_cModule.  And sandkit->rb_eException is derived from sandkit->rb_cModule.
> 
> ? It is assuming that argv[0] to be an instance of subclass of Module,
> this means Foo in
> 
>   begin
>     ...
>   rescue Foo
>     ...
>   end
> 
> to be a module or a class, not that Exception to be a subclass of
> Module, but Exception to be an instance of a Class, which is true even
> within the sandboxes I guess.  Am I missing something?

I will try to approach this differently.  Is there a way to circumvent ensure?
In other words: can you kill this thread?

  th =
  Thread.start do
    def endless
      begin
        loop {}
      ensure
        endless
      end
    end

    endless
  end

I cannot.

  th.kill  # hangs
  th.raise Interrupt while th.active?  # eternal ping-pong

Now, let us see what Exceptions are in the sandbox and out of the sandbox.

  >> require 'sandbox'
  => true
  >> s = Sandbox.new
  => #<Sandbox:0x82da390>
  >> s.eval("Exception")
  => Exception
  >> Exception.is_a? Object
  => true
  >> s.eval("Exception").is_a? Object
  => false
  >> s.eval("Exception").is_a? s.eval("Object")
  => true

You see?  Normal rb_eException < rb_cObject.  But, kit->eException <
kit->cObject.

So, knowing all of that, it is insecure for `rescue` in the sandbox to catch a
normal rb_eException.  Ruby does, too.  Ruby won't allow it.  I also feel it is
insecure for `ensure` in the sandbox to intercept _some_ exceptions.  But
`ensure` even catches TAG_FATAL.  It is good at it's job!

_why