ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:82100] [Ruby trunk Bug#13753] Segfault when calling `Random::DEFAULT.rand` in forked child
       [not found] <redmine.issue-13753.20170718163323@ruby-lang.org>
@ 2017-07-18 16:33 ` owen
  2017-07-18 16:47 ` [ruby-core:82101] " owen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 4+ messages in thread
From: owen @ 2017-07-18 16:33 UTC (permalink / raw
  To: ruby-core

Issue #13753 has been reported by owst (Owen Stephens).

----------------------------------------
Bug #13753: Segfault when calling `Random::DEFAULT.rand` in forked child
https://bugs.ruby-lang.org/issues/13753

* Author: owst (Owen Stephens)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]
* Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN
----------------------------------------
Hi,

The following causes a segfault on 2.3.4, 2.4.1 and current (`ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]`)

~~~ ruby
puts "before fork: #{Random::DEFAULT.rand(42)}"

fork do
  puts "child: #{Random::DEFAULT.rand(42)}"
end
~~~

~~~
/home/owen/fork_random.rb:4: [BUG] Segmentation fault at 0x0000000000000000
ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0005 p:---- s:0020 e:000019 CFUNC  :rand
c:0004 p:0021 s:0015 e:000012 BLOCK  /home/owen/fork_random.rb:4 [FINISH]
c:0003 p:---- s:0010 e:000009 CFUNC  :fork
c:0002 p:0033 s:0006 e:000005 EVAL   /home/owen/fork_random.rb:3 [FINISH]
c:0001 p:0000 s:0003 E:000790 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
/home/owen/fork_random.rb:3:in `<main>'
/home/owen/fork_random.rb:3:in `fork'
/home/owen/fork_random.rb:4:in `block in <main>'
/home/owen/fork_random.rb:4:in `rand'

-- Machine register context ------------------------------------------------
 RIP: 0x00007f99e9e7eefd RBP: 0x00007fff14180190 RSP: 0x00007fff14180178
 RAX: 0x0000000000000000 RBX: 0x00007f99ea17b039 RCX: 0x0000000000000004
 RDX: 0x00007f99ea2af228 RDI: 0x00007f99ea2af228 RSI: 0x0000000000000029
  R8: 0x0000000000000000  R9: 0x00007f99eb0b5630 R10: 0x0000000022220021
 R11: 0x00007f99ea17b060 R12: 0x00007f99e9dd96a0 R13: 0x00007fff14182df0
 R14: 0x00007f99eb3d3248 R15: 0x00007f99ea27af50 EFL: 0x0000000000010202

-- C level backtrace information -------------------------------------------
/home/owen/code/ruby/ruby(rb_print_backtrace+0x19) [0x7f99e9f4e081] vm_dump.c:671
/home/owen/code/ruby/ruby(rb_vm_bugreport+0xb3) [0x7f99e9f4e4fd] vm_dump.c:941
/home/owen/code/ruby/ruby(rb_bug_context+0x117) [0x7f99e9fc098e] error.c:534
/home/owen/code/ruby/ruby(sigsegv+0x60) [0x7f99e9ec8793] signal.c:930
/lib/x86_64-linux-gnu/libpthread.so.0 [0x7f99e9983330]
/home/owen/code/ruby/ruby(genrand_int32+0x57) [0x7f99e9e7eefd] random.c:189
/home/owen/code/ruby/ruby(limited_rand+0xb6) [0x7f99e9e7fda1] random.c:839
/home/owen/code/ruby/ruby(random_ulong_limited+0x142) [0x7f99e9e80483] random.c:1019
/home/owen/code/ruby/ruby(rand_int+0x74) [0x7f99e9e80a09] random.c:1149
/home/owen/code/ruby/ruby(rand_random+0xe3) [0x7f99e9e811a2] random.c:1337
/home/owen/code/ruby/ruby(random_rand+0x34) [0x7f99e9e810a2] random.c:1320
/home/owen/code/ruby/ruby(call_cfunc_m1+0x2f) [0x7f99e9f2f3dd] vm_insnhelper.c:1706
/home/owen/code/ruby/ruby(vm_call_cfunc_with_frame+0x19a) [0x7f99e9f2ff10] vm_insnhelper.c:1889

~~~

The problem is in the `rb_reset_random_seed` call that happens after forking a Thread. This function call places the `struct mt` inside `default_rand` in a partially-uninitialised state and the next call to `rand_int` (which assumes the `struct mt` _is_ initialised) tries to dereference a null pointer.

N.B. the first call to `Random::DEFAULT.rand` is required to exhibit the bug else the Random instance is not placed into an inconsistent state upon forking (in particular `mt->left == 1` so the next rand call correctly re-initialises the instance)




-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:82101] [Ruby trunk Bug#13753] Segfault when calling `Random::DEFAULT.rand` in forked child
       [not found] <redmine.issue-13753.20170718163323@ruby-lang.org>
  2017-07-18 16:33 ` [ruby-core:82100] [Ruby trunk Bug#13753] Segfault when calling `Random::DEFAULT.rand` in forked child owen
@ 2017-07-18 16:47 ` owen
  2017-08-05  6:46 ` [ruby-core:82256] " nagachika00
  2017-08-09 10:32 ` [ruby-core:82303] " usa
  3 siblings, 0 replies; 4+ messages in thread
From: owen @ 2017-07-18 16:47 UTC (permalink / raw
  To: ruby-core

Issue #13753 has been updated by owst (Owen Stephens).

File 0001-Re-initialise-Random-DEFAULT-after-forking-Bug-13753.patch added

The attached patch fixes the issue by re-initialising the random instance such that calls to `Random::DEFAULT.rand` after forking will succeed. 

This now gives the same after-fork behaviour as `Random.rand`. Incidentally, there is a comment on `Random.rand` saying:

~~~ ruby
 * Alias of Random::DEFAULT.rand.
~~~

which is now true in the sense that they behave the same.

----------------------------------------
Bug #13753: Segfault when calling `Random::DEFAULT.rand` in forked child
https://bugs.ruby-lang.org/issues/13753#change-65840

* Author: owst (Owen Stephens)
* Status: Open
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]
* Backport: 2.2: UNKNOWN, 2.3: UNKNOWN, 2.4: UNKNOWN
----------------------------------------
Hi,

The following causes a segfault on 2.3.4, 2.4.1 and current (`ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]`)

~~~ ruby
puts "before fork: #{Random::DEFAULT.rand(42)}"

fork do
  puts "child: #{Random::DEFAULT.rand(42)}"
end
~~~

~~~
/home/owen/fork_random.rb:4: [BUG] Segmentation fault at 0x0000000000000000
ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0005 p:---- s:0020 e:000019 CFUNC  :rand
c:0004 p:0021 s:0015 e:000012 BLOCK  /home/owen/fork_random.rb:4 [FINISH]
c:0003 p:---- s:0010 e:000009 CFUNC  :fork
c:0002 p:0033 s:0006 e:000005 EVAL   /home/owen/fork_random.rb:3 [FINISH]
c:0001 p:0000 s:0003 E:000790 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
/home/owen/fork_random.rb:3:in `<main>'
/home/owen/fork_random.rb:3:in `fork'
/home/owen/fork_random.rb:4:in `block in <main>'
/home/owen/fork_random.rb:4:in `rand'

-- Machine register context ------------------------------------------------
 RIP: 0x00007f99e9e7eefd RBP: 0x00007fff14180190 RSP: 0x00007fff14180178
 RAX: 0x0000000000000000 RBX: 0x00007f99ea17b039 RCX: 0x0000000000000004
 RDX: 0x00007f99ea2af228 RDI: 0x00007f99ea2af228 RSI: 0x0000000000000029
  R8: 0x0000000000000000  R9: 0x00007f99eb0b5630 R10: 0x0000000022220021
 R11: 0x00007f99ea17b060 R12: 0x00007f99e9dd96a0 R13: 0x00007fff14182df0
 R14: 0x00007f99eb3d3248 R15: 0x00007f99ea27af50 EFL: 0x0000000000010202

-- C level backtrace information -------------------------------------------
/home/owen/code/ruby/ruby(rb_print_backtrace+0x19) [0x7f99e9f4e081] vm_dump.c:671
/home/owen/code/ruby/ruby(rb_vm_bugreport+0xb3) [0x7f99e9f4e4fd] vm_dump.c:941
/home/owen/code/ruby/ruby(rb_bug_context+0x117) [0x7f99e9fc098e] error.c:534
/home/owen/code/ruby/ruby(sigsegv+0x60) [0x7f99e9ec8793] signal.c:930
/lib/x86_64-linux-gnu/libpthread.so.0 [0x7f99e9983330]
/home/owen/code/ruby/ruby(genrand_int32+0x57) [0x7f99e9e7eefd] random.c:189
/home/owen/code/ruby/ruby(limited_rand+0xb6) [0x7f99e9e7fda1] random.c:839
/home/owen/code/ruby/ruby(random_ulong_limited+0x142) [0x7f99e9e80483] random.c:1019
/home/owen/code/ruby/ruby(rand_int+0x74) [0x7f99e9e80a09] random.c:1149
/home/owen/code/ruby/ruby(rand_random+0xe3) [0x7f99e9e811a2] random.c:1337
/home/owen/code/ruby/ruby(random_rand+0x34) [0x7f99e9e810a2] random.c:1320
/home/owen/code/ruby/ruby(call_cfunc_m1+0x2f) [0x7f99e9f2f3dd] vm_insnhelper.c:1706
/home/owen/code/ruby/ruby(vm_call_cfunc_with_frame+0x19a) [0x7f99e9f2ff10] vm_insnhelper.c:1889

~~~

The problem is in the `rb_reset_random_seed` call that happens after forking a Thread. This function call places the `struct mt` inside `default_rand` in a partially-uninitialised state and the next call to `rand_int` (which assumes the `struct mt` _is_ initialised) tries to dereference a null pointer.

N.B. the first call to `Random::DEFAULT.rand` is required to exhibit the bug else the Random instance is not placed into an inconsistent state upon forking (in particular `mt->left == 1` so the next rand call correctly re-initialises the instance)


---Files--------------------------------
0001-Re-initialise-Random-DEFAULT-after-forking-Bug-13753.patch (1.21 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:82256] [Ruby trunk Bug#13753] Segfault when calling `Random::DEFAULT.rand` in forked child
       [not found] <redmine.issue-13753.20170718163323@ruby-lang.org>
  2017-07-18 16:33 ` [ruby-core:82100] [Ruby trunk Bug#13753] Segfault when calling `Random::DEFAULT.rand` in forked child owen
  2017-07-18 16:47 ` [ruby-core:82101] " owen
@ 2017-08-05  6:46 ` nagachika00
  2017-08-09 10:32 ` [ruby-core:82303] " usa
  3 siblings, 0 replies; 4+ messages in thread
From: nagachika00 @ 2017-08-05  6:46 UTC (permalink / raw
  To: ruby-core

Issue #13753 has been updated by nagachika (Tomoyuki Chikanaga).

Backport changed from 2.2: REQUIRED, 2.3: REQUIRED, 2.4: REQUIRED to 2.2: REQUIRED, 2.3: REQUIRED, 2.4: DONE

ruby_2_4 r59517 merged revision(s) 59368.

----------------------------------------
Bug #13753: Segfault when calling `Random::DEFAULT.rand` in forked child
https://bugs.ruby-lang.org/issues/13753#change-66036

* Author: owst (Owen Stephens)
* Status: Closed
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]
* Backport: 2.2: REQUIRED, 2.3: REQUIRED, 2.4: DONE
----------------------------------------
Hi,

The following causes a segfault on 2.3.4, 2.4.1 and current (`ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]`)

~~~ ruby
puts "before fork: #{Random::DEFAULT.rand(42)}"

fork do
  puts "child: #{Random::DEFAULT.rand(42)}"
end
~~~

~~~
/home/owen/fork_random.rb:4: [BUG] Segmentation fault at 0x0000000000000000
ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0005 p:---- s:0020 e:000019 CFUNC  :rand
c:0004 p:0021 s:0015 e:000012 BLOCK  /home/owen/fork_random.rb:4 [FINISH]
c:0003 p:---- s:0010 e:000009 CFUNC  :fork
c:0002 p:0033 s:0006 e:000005 EVAL   /home/owen/fork_random.rb:3 [FINISH]
c:0001 p:0000 s:0003 E:000790 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
/home/owen/fork_random.rb:3:in `<main>'
/home/owen/fork_random.rb:3:in `fork'
/home/owen/fork_random.rb:4:in `block in <main>'
/home/owen/fork_random.rb:4:in `rand'

-- Machine register context ------------------------------------------------
 RIP: 0x00007f99e9e7eefd RBP: 0x00007fff14180190 RSP: 0x00007fff14180178
 RAX: 0x0000000000000000 RBX: 0x00007f99ea17b039 RCX: 0x0000000000000004
 RDX: 0x00007f99ea2af228 RDI: 0x00007f99ea2af228 RSI: 0x0000000000000029
  R8: 0x0000000000000000  R9: 0x00007f99eb0b5630 R10: 0x0000000022220021
 R11: 0x00007f99ea17b060 R12: 0x00007f99e9dd96a0 R13: 0x00007fff14182df0
 R14: 0x00007f99eb3d3248 R15: 0x00007f99ea27af50 EFL: 0x0000000000010202

-- C level backtrace information -------------------------------------------
/home/owen/code/ruby/ruby(rb_print_backtrace+0x19) [0x7f99e9f4e081] vm_dump.c:671
/home/owen/code/ruby/ruby(rb_vm_bugreport+0xb3) [0x7f99e9f4e4fd] vm_dump.c:941
/home/owen/code/ruby/ruby(rb_bug_context+0x117) [0x7f99e9fc098e] error.c:534
/home/owen/code/ruby/ruby(sigsegv+0x60) [0x7f99e9ec8793] signal.c:930
/lib/x86_64-linux-gnu/libpthread.so.0 [0x7f99e9983330]
/home/owen/code/ruby/ruby(genrand_int32+0x57) [0x7f99e9e7eefd] random.c:189
/home/owen/code/ruby/ruby(limited_rand+0xb6) [0x7f99e9e7fda1] random.c:839
/home/owen/code/ruby/ruby(random_ulong_limited+0x142) [0x7f99e9e80483] random.c:1019
/home/owen/code/ruby/ruby(rand_int+0x74) [0x7f99e9e80a09] random.c:1149
/home/owen/code/ruby/ruby(rand_random+0xe3) [0x7f99e9e811a2] random.c:1337
/home/owen/code/ruby/ruby(random_rand+0x34) [0x7f99e9e810a2] random.c:1320
/home/owen/code/ruby/ruby(call_cfunc_m1+0x2f) [0x7f99e9f2f3dd] vm_insnhelper.c:1706
/home/owen/code/ruby/ruby(vm_call_cfunc_with_frame+0x19a) [0x7f99e9f2ff10] vm_insnhelper.c:1889

~~~

The problem is in the `rb_reset_random_seed` call that happens after forking a Thread. This function call places the `struct mt` inside `default_rand` in a partially-uninitialised state and the next call to `rand_int` (which assumes the `struct mt` _is_ initialised) tries to dereference a null pointer.

N.B. the first call to `Random::DEFAULT.rand` is required to exhibit the bug else the Random instance is not placed into an inconsistent state upon forking (in particular `mt->left == 1` so the next rand call correctly re-initialises the instance)


---Files--------------------------------
0001-Re-initialise-Random-DEFAULT-after-forking-Bug-13753.patch (1.21 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:82303] [Ruby trunk Bug#13753] Segfault when calling `Random::DEFAULT.rand` in forked child
       [not found] <redmine.issue-13753.20170718163323@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2017-08-05  6:46 ` [ruby-core:82256] " nagachika00
@ 2017-08-09 10:32 ` usa
  3 siblings, 0 replies; 4+ messages in thread
From: usa @ 2017-08-09 10:32 UTC (permalink / raw
  To: ruby-core

Issue #13753 has been updated by usa (Usaku NAKAMURA).

Backport changed from 2.2: REQUIRED, 2.3: REQUIRED, 2.4: DONE to 2.2: REQUIRED, 2.3: DONE, 2.4: DONE

ruby_2_3 r59546 merged revision(s) 59368.

----------------------------------------
Bug #13753: Segfault when calling `Random::DEFAULT.rand` in forked child
https://bugs.ruby-lang.org/issues/13753#change-66097

* Author: owst (Owen Stephens)
* Status: Closed
* Priority: Normal
* Assignee: 
* Target version: 
* ruby -v: ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]
* Backport: 2.2: REQUIRED, 2.3: DONE, 2.4: DONE
----------------------------------------
Hi,

The following causes a segfault on 2.3.4, 2.4.1 and current (`ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]`)

~~~ ruby
puts "before fork: #{Random::DEFAULT.rand(42)}"

fork do
  puts "child: #{Random::DEFAULT.rand(42)}"
end
~~~

~~~
/home/owen/fork_random.rb:4: [BUG] Segmentation fault at 0x0000000000000000
ruby 2.5.0dev (2017-07-18 trunk 59362) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0005 p:---- s:0020 e:000019 CFUNC  :rand
c:0004 p:0021 s:0015 e:000012 BLOCK  /home/owen/fork_random.rb:4 [FINISH]
c:0003 p:---- s:0010 e:000009 CFUNC  :fork
c:0002 p:0033 s:0006 e:000005 EVAL   /home/owen/fork_random.rb:3 [FINISH]
c:0001 p:0000 s:0003 E:000790 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
/home/owen/fork_random.rb:3:in `<main>'
/home/owen/fork_random.rb:3:in `fork'
/home/owen/fork_random.rb:4:in `block in <main>'
/home/owen/fork_random.rb:4:in `rand'

-- Machine register context ------------------------------------------------
 RIP: 0x00007f99e9e7eefd RBP: 0x00007fff14180190 RSP: 0x00007fff14180178
 RAX: 0x0000000000000000 RBX: 0x00007f99ea17b039 RCX: 0x0000000000000004
 RDX: 0x00007f99ea2af228 RDI: 0x00007f99ea2af228 RSI: 0x0000000000000029
  R8: 0x0000000000000000  R9: 0x00007f99eb0b5630 R10: 0x0000000022220021
 R11: 0x00007f99ea17b060 R12: 0x00007f99e9dd96a0 R13: 0x00007fff14182df0
 R14: 0x00007f99eb3d3248 R15: 0x00007f99ea27af50 EFL: 0x0000000000010202

-- C level backtrace information -------------------------------------------
/home/owen/code/ruby/ruby(rb_print_backtrace+0x19) [0x7f99e9f4e081] vm_dump.c:671
/home/owen/code/ruby/ruby(rb_vm_bugreport+0xb3) [0x7f99e9f4e4fd] vm_dump.c:941
/home/owen/code/ruby/ruby(rb_bug_context+0x117) [0x7f99e9fc098e] error.c:534
/home/owen/code/ruby/ruby(sigsegv+0x60) [0x7f99e9ec8793] signal.c:930
/lib/x86_64-linux-gnu/libpthread.so.0 [0x7f99e9983330]
/home/owen/code/ruby/ruby(genrand_int32+0x57) [0x7f99e9e7eefd] random.c:189
/home/owen/code/ruby/ruby(limited_rand+0xb6) [0x7f99e9e7fda1] random.c:839
/home/owen/code/ruby/ruby(random_ulong_limited+0x142) [0x7f99e9e80483] random.c:1019
/home/owen/code/ruby/ruby(rand_int+0x74) [0x7f99e9e80a09] random.c:1149
/home/owen/code/ruby/ruby(rand_random+0xe3) [0x7f99e9e811a2] random.c:1337
/home/owen/code/ruby/ruby(random_rand+0x34) [0x7f99e9e810a2] random.c:1320
/home/owen/code/ruby/ruby(call_cfunc_m1+0x2f) [0x7f99e9f2f3dd] vm_insnhelper.c:1706
/home/owen/code/ruby/ruby(vm_call_cfunc_with_frame+0x19a) [0x7f99e9f2ff10] vm_insnhelper.c:1889

~~~

The problem is in the `rb_reset_random_seed` call that happens after forking a Thread. This function call places the `struct mt` inside `default_rand` in a partially-uninitialised state and the next call to `rand_int` (which assumes the `struct mt` _is_ initialised) tries to dereference a null pointer.

N.B. the first call to `Random::DEFAULT.rand` is required to exhibit the bug else the Random instance is not placed into an inconsistent state upon forking (in particular `mt->left == 1` so the next rand call correctly re-initialises the instance)


---Files--------------------------------
0001-Re-initialise-Random-DEFAULT-after-forking-Bug-13753.patch (1.21 KB)


-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-08-09 10:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <redmine.issue-13753.20170718163323@ruby-lang.org>
2017-07-18 16:33 ` [ruby-core:82100] [Ruby trunk Bug#13753] Segfault when calling `Random::DEFAULT.rand` in forked child owen
2017-07-18 16:47 ` [ruby-core:82101] " owen
2017-08-05  6:46 ` [ruby-core:82256] " nagachika00
2017-08-09 10:32 ` [ruby-core:82303] " usa

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).