Problems with resolv.rb && Queue/Thread

Platform: Solaris 8
Ruby Versions: 1.8.0/2003-08-04
1.9.0/2004-01-13

I’m writing a simple port scanner, and it uses multiple threads to
separate out the scanning functions and a Queue to collect the scan
info.

I was attempting to use Resolv.getname within each thread to lookup the
hostname of a given IP, and I’m getting errors from within the Resolv
module:

% ruby scratch/scan -p 25 10.0.2.{1,3,5,7,9,11}.{0,32,64,96,128,160,192,224}/27 | m
/usr/local/lib/ruby/1.8/resolv.rb:539:in delete': undefined method queue’ for 7:Fixnum (NoMethodError)
from /usr/local/lib/ruby/1.8/resolv.rb:539:in delete_if' from /usr/local/lib/ruby/1.8/resolv.rb:539:in delete’
from /usr/local/lib/ruby/1.8/resolv.rb:482:in each_resource' from /usr/local/lib/ruby/1.8/resolv.rb:441:in each_name’
from /usr/local/lib/ruby/1.8/resolv.rb:258:in each_name' from /usr/local/lib/ruby/1.8/resolv.rb:257:in each’
from /usr/local/lib/ruby/1.8/resolv.rb:257:in each_name' from /usr/local/lib/ruby/1.8/resolv.rb:245:in getname’
… 11 levels…
from scratch/scan:53:in Main' from scratch/scan:52:in each’
from scratch/scan:52:in `Main’
from scratch/scan:124

The above error is relatively consistent with 1.8, but not 1.9:

/usr/local/lib/ruby/1.9/resolv.rb:539:in delete': undefined method queue’ for 7:Fixnum (NoMethodError)
/usr/local/lib/ruby/1.9/resolv.rb:539:in delete': undefined method queue’ for nil:NilClass (NoMethodError)
/usr/local/lib/ruby/1.9/resolv.rb:539:in `delete’/cise/homes/jfh/scratch/scan:63: [BUG] Segmentation fault

Here is the offending code:

ARGV.each { |ipaddr|
    threads << Thread.new {
        ips = Hash.new { |h,k| h[k] = [] }
        IP4NetAddr.new(ipaddr).all { |ip|

scan.txt (2.78 KB)

netaddr.rb.txt (3.47 KB)

···

            # Lookup name
            #

            begin

—> timeout(0.2) { puts Resolv.getname(ip) }
rescue Timeout::Error, Resolv::ResolvError
end

When I comment out the code here and move it back out to the main thread, the problem
does not occur. Also, the problem does not seem to occur on FreeBSD 4.9 or Mandrake
Linux 9.1.

Attached is the scanner and netaddr.rb (at some point I want to patch ipaddr.rb
to be able to do each and all, but I haven’t gotten around to it yet).

Anyone know what’s going on?


Jim Hranicky, Senior SysAdmin UF/CISE Department |
E314D CSE Building Phone (352) 392-1499 |
jfh@cise.ufl.edu http://www.cise.ufl.edu/~jfh |


                      About politics:
                 Don't worry about results
               It's the thought that counts

“James F. Hranicky” jfh@cise.ufl.edu schrieb im Newsbeitrag
news:20040123095748.5711f5e0.jfh@cise.ufl.edu…

Platform: Solaris 8
Ruby Versions: 1.8.0/2003-08-04
1.9.0/2004-01-13

I’m writing a simple port scanner, and it uses multiple threads to
separate out the scanning functions and a Queue to collect the scan
info.

I was attempting to use Resolv.getname within each thread to lookup the
hostname of a given IP, and I’m getting errors from within the Resolv
module:

% ruby scratch/scan -p 25
10.0.2.{1,3,5,7,9,11}.{0,32,64,96,128,160,192,224}/27 | m
/usr/local/lib/ruby/1.8/resolv.rb:539:in delete': undefined method queue’ for 7:Fixnum (NoMethodError)
from /usr/local/lib/ruby/1.8/resolv.rb:539:in delete_if' from /usr/local/lib/ruby/1.8/resolv.rb:539:in delete’
from /usr/local/lib/ruby/1.8/resolv.rb:482:in each_resource' from /usr/local/lib/ruby/1.8/resolv.rb:441:in each_name’
from /usr/local/lib/ruby/1.8/resolv.rb:258:in each_name' from /usr/local/lib/ruby/1.8/resolv.rb:257:in each’
from /usr/local/lib/ruby/1.8/resolv.rb:257:in each_name' from /usr/local/lib/ruby/1.8/resolv.rb:245:in getname’
… 11 levels…
from scratch/scan:53:in Main' from scratch/scan:52:in each’
from scratch/scan:52:in `Main’
from scratch/scan:124

The above error is relatively consistent with 1.8, but not 1.9:

/usr/local/lib/ruby/1.9/resolv.rb:539:in delete': undefined method queue’ for 7:Fixnum (NoMethodError)
/usr/local/lib/ruby/1.9/resolv.rb:539:in delete': undefined method queue’ for nil:NilClass (NoMethodError)
/usr/local/lib/ruby/1.9/resolv.rb:539:in
`delete’/cise/homes/jfh/scratch/scan:63: [BUG] Segmentation fault

Here is the offending code:

ARGV.each { |ipaddr|
    threads << Thread.new {
        ips = Hash.new { |h,k| h[k] = [] }
        IP4NetAddr.new(ipaddr).all { |ip|

            #
            # Lookup name
            #

            begin

—> timeout(0.2) { puts Resolv.getname(ip) }
rescue Timeout::Error, Resolv::ResolvError
end

When I comment out the code here and move it back out to the main
thread, the problem
does not occur. Also, the problem does not seem to occur on FreeBSD 4.9
or Mandrake
Linux 9.1.

Attached is the scanner and netaddr.rb (at some point I want to patch
ipaddr.rb
to be able to do each and all, but I haven’t gotten around to it yet).

Anyone know what’s going on?

Not exactly. But your code has a subtle error. It should read

ARGV.each { |ipaddr|
threads << Thread.new( ipaddr ) { |local_ipaddr|

IP4NetAddr.new(local_ipaddr).all { |ip|

Otherwise the threads access the variable defined in the ARGV.each block
and thus errors might occur since you’re not accessing the value you think
you are.

Kind regards

robert

I tried it and got this with 1.8:

/usr/local/lib/ruby/1.8/resolv.rb:539:in delete': undefined method queue’ for 6:Fixnum (NoMethodError)

1.9 seems unchanged.

Thanks…I’ll keep scanning for un-thread-safe code.

Jim

···

On Sat, 24 Jan 2004 00:44:58 +0900 “Robert Klemme” bob.news@gmx.net wrote:

Not exactly. But your code has a subtle error. It should read

ARGV.each { |ipaddr|
threads << Thread.new( ipaddr ) { |local_ipaddr|

IP4NetAddr.new(local_ipaddr).all { |ip|

Otherwise the threads access the variable defined in the ARGV.each block
and thus errors might occur since you’re not accessing the value you think
you are.