Bug #7499

public_send can be used to invoke protected methods

Added by Andy Lindeman over 1 year ago. Updated over 1 year ago.

[ruby-core:50489]
Status:Closed
Priority:Normal
Assignee:-
Category:-
Target version:-
ruby -v:ruby 2.0.0dev (2012-12-03) [x86_64-darwin12.2.1] Backport:

Description

class Foo
def bar
"wtf?"
end
protected :bar

def invokebar
public
send(:bar)
end
end

puts Foo.public_send(:bar) rescue puts "error; this seems normal"

puts Foo.new.invoke_bar

The last statement outputs "wtf?" on:

* 1.9.3p194

* 1.9.3p327

* ruby-head (2012-12-03)

The last statement raises a NoMethodError on:

* JRuby 1.7.0

* rubinius 2.0.0dev 2279857e

#

I /expected/ the NoMethodError behavior

bug-7499.patch Magnifier (2.7 KB) Charlie Somerville, 12/03/2012 08:10 PM

Associated revisions

Revision 38223
Added by Nobuyoshi Nakada over 1 year ago

vmeval.c: publicsend does not consider how it is called

  • vmeval.c (rbmethodcallstatus): use Qundef as no self instead of the current self.
  • vmeval.c (sendinternal): public_send does not consider how it is called, as mentioned in r14173. patched by charliesome (Charlie Somerville). [Bug #7499]

History

#1 Updated by Charlie Somerville over 1 year ago

rbmethodcall_status checks the value of 'self' at the callsite to determine whether protected methods can be called.

Unfortunately this means calls to protected methods via public_send will erroneously succeed if they are in the right scope.

To fix this, I changed the meaning of Qundef as the 'self' argument to rbcall0. Formerly, Qundef meant 'use the self from the current control frame'. Now, Qundef means 'do not consider self so protected methods cannot be called'. I have updated the few calls to rbcall0 to fetch 'self' from the control frame manually. As rbcall0 and rbmethodcallstatus are static, there is no concern for ABI breakage.

#2 Updated by Marc-Andre Lafortune over 1 year ago

Looks good to me.

#3 Updated by Nobuyoshi Nakada over 1 year ago

  • Status changed from Open to Closed
  • % Done changed from 0 to 100

This issue was solved with changeset r38223.
Andy, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


vmeval.c: publicsend does not consider how it is called

  • vmeval.c (rbmethodcallstatus): use Qundef as no self instead of the current self.
  • vmeval.c (sendinternal): public_send does not consider how it is called, as mentioned in r14173. patched by charliesome (Charlie Somerville). [Bug #7499]

Also available in: Atom PDF