--k1lZvvs/B4yU6o8G Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sun, Oct 15, 2006 at 05:33:16PM +0900, Eric Hodel wrote: > > Please attach the testcase. OK, i have stripped down the testcase further. The program does not make much sense anymore, but still shows the bug: The program calls IPAddrRange.new("192.168.0.0-192.168.255.255") twice, once directly and once hidden within the Whois.get("192.168.155.1") call. Althoug both calls to IPAddrRange.new do the very same, it works for the first time and then it fails for the second time, because the regular expression engine seems to have gone into a state where it keeps tainting any results. When I run the attached program the output looks like this: % ruby WhoisBug.rb IPAddrRangeInit 192.168.0.0-192.168.255.255 Tainted false SAFETainted arg false 192.168.0.0-192.168.255.255 SAFETainted v false |192.168.0.0| Tainted b false |192.168.255.255| 192.168.0.0-192.168.255.255 IPAddrRangeInit 192.168.0.0-192.168.255.255 Tainted false SAFETainted arg false 192.168.0.0-192.168.255.255 SAFETainted v false |192.168.0.0| Tainted b false |192.168.255.255| Exception: invalid address (ArgumentError) /usr/lib/ruby/1.8/ipaddr.rb:422:in `initialize' WhoisBug.rb:27:in `new' WhoisBug.rb:27:in `initialize' WhoisBug.rb:159:in `new' WhoisBug.rb:159:in `parse' WhoisBug.rb:137:in `each' WhoisBug.rb:137:in `parse' WhoisBug.rb:94:in `get_whois_net' WhoisBug.rb:76:in `get' WhoisBug.rb:186 So calling the same thing twice works only in the first time. regards Hadmut --k1lZvvs/B4yU6o8G Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="WhoisBug.rb" # Copyright 2003-2006 Hadmut Danisch, hadmut / danisch.de require 'thread' require 'monitor' require 'ipaddr' ########################################################################## class IPAddrRange attr_reader :von, :bis, :mask_len def initialize(arg) @von,@bis,@mask l,nil,nil $stderr.puts "IPAddrRangeInit #{arg} Tainted #{arg.tainted?} SAFE $SAFE}" case arg when /^([\da-f\.:]+)\s*-\s*([\da-f\.:]+)$/i v,b.untaint,$2.untaint $stderr.puts "Tainted arg #{arg.tainted?} #{arg} SAFE $SAFE}" $stderr.puts "Tainted v #{v.tainted?} |#{v}|" $stderr.puts "Tainted b #{b.tainted?} |#{b}|" @von Addr.new(v) @bis Addr.new(b) else raise "Address Range Syntax" end $stderr.puts end def to_s @von.to_s + "-" + @bis.to_s end end ########################################################################### class WhoisData attr_reader :country,:org,:range,:id,:typ def initialize(country,org,range,id l,typ l) @country,@org,@rangentry,org,range @id @typ end def to_s "#{@country}: #{@org} #{@range}" end end ########################################################################### module Whois def Whois.get(ipaddr,dbmutex l) ipaddr PAddr.new(ipaddr) addrkey paddr.native result hois.get_whois_net(addrkey) return result end ########################################################################### def Whois.get_whois_net(net,host l) #whois jwhois -d #{net}` # jwhois call replaced with static data for debugging purposes whois ENDE OrgName: Internet Assigned Numbers Authority Country: US NetRange: 192.168.0.0 - 192.168.255.255 ENDE whois.taint Whois.parse(whois) end ########################################################################### def Whois.parse(whois) case whois when String whois ois.split("\n") when Array # ok else raise "Argument #{whois.class}" end wh } for zeile in whois do zeile.delete!("\r\n") #puts "Z #{zeile}" case zeile when /^(\w[\w ]+\w)\s*:\s*([-_\s\w\.\,\(\)\/]+)$/ wh[$1] unless wh.has_key?($1) end end #wh.keys.sort.each{|k| printf "%-20.20s %s\n",k,wh[k]} # Here the bug begins: # Problem does not occur if we pass back the same results directly # return "US","IANA",IPAddrRange.new("192.168.0.0 - 192.168.255.255") for i in [ ["NetRange", "OrgName", "Country"], ["NetRange", "NetName", "Country"], ] do netkey,orgkey,countrykey if wh.has_key?(netkey) && wh.has_key?(orgkey) && wh.has_key?(countrykey) addr [netkey].gsub(" ","") case addr when /^[-\.\d]+$/ addr¥ådr.untaint else raise "Address syntax" end #$stderr.puts "Angekommen #{wh[orgkey]} |#{wh[netkey]}|#{addr}|#{addr.tainted?}" return WhoisData.new(wh[countrykey], wh[orgkey], IPAddrRange.new(addr)) end #if end #for return nil end end ########################################################################### if __FILE__ $0 begin $SAFE puts IPAddrRange.new("192.168.0.0-192.168.255.255") puts puts Whois.get("192.168.155.1") rescue SystemExit raise rescue Exception exc $stderr.puts "Exception: #{exc} (#{exc.class.to_s})" $stderr.puts exc.backtrace exit 99 end end --k1lZvvs/B4yU6o8G--