This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Ruby on Rails 2.0.2/Cygwin Bug


On Dec 21 22:13, Mike Boone wrote:
> I came up with a simple Ruby snippet that reproduces the problem. I'd
> appreciate it if other Cygwin users would try it. You can change the
> "cause_failure = true" line to say false and it will run.
> 
> --urandom_test.rb------
> # Test failure of reading /dev/urandom after failed require
> 
> # this method is from the Rails' source secret_key_generator.rb
> def generate_secret_with_urandom
>   return File.read("/dev/urandom", 64).unpack("H*")[0]
> end
> 
> cause_failure = true
> 
> begin
>   require 'nonexistent_file'
> rescue LoadError
>   puts '' unless cause_failure
> end
> 
> puts generate_secret_with_urandom
> -----------------------

Looks like a bug in ruby.  First of all, this works fine under Cygwin:

  $ dd if=/dev/urandom bs=64 count=1 | od -c
  1+0 records in
  1+0 records out
  64 bytes (64 B) copied, 0.39 s, 0.2 kB/s
  0000000 9d78 007a 8e7c 0cad 5d1c 6778 1298 88a9
  0000020 4256 8e69 be6f c3b5 be0a 695e 9446 5689
  0000040 db44 8a04 0159 175c b84e 79cf 0ebc 9ee7
  0000060 7e3d 8338 31bd b8e7 15df ab91 ea55 90b6
  0000100

And this, too:

  $ dd if=/dev/urandom of=/dev/urandom bs=64 count=1 
  1+0 records in
  1+0 records out
  64 bytes (64 B) copied, 0.015 s, 4.3 kB/s

Running the above ruby script under strace shows:

 1345 2541402 [main] ruby 3012 open: open (/dev/urandom, 0x0)
 [...]
  255 2543760 [main] ruby 3012 open: 3 = open (/dev/urandom, 0x0)

It now has a valid file descriptor.

  606 2544366 [main] ruby 3012 _cygwin_istext_for_stdio: fd 3: opened as binary
 2272 2546638 [main] ruby 3012 fhandler_base::fstat: here
  349 2546987 [main] ruby 3012 fstat64: 0 = fstat (3, 0x2409720)

fstat returned successfully.

  687 2547674 [main] ruby 3012 isatty: 0 = isatty (3)

/dev/urandom is obviously no tty.

  358 2548032 [main] ruby 3012 readv: readv (3, 0x2409740, 1) blocking, sigcatchers 10
  216 2548248 [main] ruby 3012 readv: no need to call ready_for_read
35355 2583603 [main] ruby 3012 readv: 65536 = readv (3, 0x2409740, 1), errno 2

read returned successfully with 64K random bytes in the buffer.

51453 2635056 [main] ruby 3012 lseek64: 0 = lseek (3, 0, 1)
  660 2635716 [main] ruby 3012 lseek64: 0 = lseek (3, -65472, 0)

Two lseek's of dubious purpose.  Why did it read 64K and then tries to
seek back?  Why does it rely on the return code of the first lseek?
Doing the same on Linux returns also with 0 from the first lseek, but
with -1 from the second call and errno set to EINVAL.  However,
according to the strace, it never *tries* to call lseek on Linux.

 9782 2645498 [main] ruby 3012 close: close (3)
  304 2645802 [main] ruby 3012 close: 0 = close (3)

The file descriptor gets closed.

The above is all about /dev/urandom in the strace output.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]