Bug #4409

DRb: discrepency between DRb.here? and DRb.uri leads to failure to dereference a DrbObject

Added by Nicolas Bondoux about 3 years ago. Updated over 2 years ago.

[ruby-core:35301]
Status:Closed
Priority:Normal
Assignee:Masatoshi Seki
Category:lib
Target version:1.9.3
ruby -v:ruby 1.9.2p0 (2010-08-18 revision 29036) [i486-linux] Backport:

Description

=begin
When a reference on a local object is sent back by a client to a server, it may not be recognised as a local object during marshalling:
An object instance being sent as a reference is wrapped in a DRbObject built by makeproxy with DRbObject.new(obj); the DRbObject's uri will be the uri returned by DRb::uri.
When this reference is sent back, DRbObject::
load checks if it matches uri of current server with DRb::here? method.

The problem is that DRb.here? checks that a DRbObject uri is the same as the uri which was used by current DRbServer at his creation, while DRb.uri will return an uri created from the local socket from current thread's connection.

So, when a DRbObject it sent back, it may not be recognized as referencing a local object

Fixing DRb.here? so that it compares with the uri returned by DRb.uri should be enough to quick fix this problem, and seems safe to me.
(I call it a quick fix because I am sure that even with this change, it is possible to build some less realistics cases with the same kind of problem, due to the fact that a same reference may be valid or not depending which client sent it back ...)

Here is a very simple proof of concept:
The server:

#!/usr/bin/ruby
require 'drb'
class A
include DRb::DRbUndumped
end

class TheServer
include DRb::DRbUndumped
def initialize
@a = A.new
end

def get_a
@a
end

def isa(iA)
puts "inside is
a: current DRb.uri:#{DRb.uri}; iA.class = #{iA.class} #{iA.__drburi if DRb::DRbObject === iA}"
@a.eql? iA
end

def getToken
retVal = @@token.clone
@@token.inc
return retVal
end

end

theServer = TheServer.new
DRb.startservice(nil,theServer)
puts "DRb.uri just after start
service: #{DRb.uri}"
DRb.thread.join

#############
The client:

#!/usr/bin/ruby
require 'drb'

theServer = DRb::DRbObject.new(nil,ARGV.shift)

a = theServer.geta
puts "a.
drburi == #{a.drburi}"
puts "theServer.is
a(a) == #{theServer.is_a(a)}"

#############
the outputs:
server side:
DRb.uri just after startservice: druby://Venus:60106
inside is
a: current DRb.uri:druby://127.0.0.1:60106; iA.class = DRb::DRbObject druby://127.0.0.1:60106

client side:
a._drburi == druby://127.0.0.1:60106
theServer.is
a(a) == false

Cheers,

Nicolas
=end

Associated revisions

Revision 32254
Added by Masatoshi Seki almost 3 years ago

fix [Bug #4409]. add DRbServer#here?

History

#1 Updated by Yui NARUSE almost 3 years ago

  • Status changed from Open to Assigned
  • Assignee set to Masatoshi Seki

#2 Updated by Hiroshi Nakamura almost 3 years ago

  • Target version set to 1.9.3

#3 Updated by Masatoshi Seki almost 3 years ago

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

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


fix [Bug #4409]. add DRbServer#here?

#4 Updated by Cory Banks over 2 years ago

Nicolas, thank you for reporting this issue - http://roofracksforvan.com

Also available in: Atom PDF