Skip to content

Commit

Permalink
Prevent writing to thread/fiber-local variables from another thread
Browse files Browse the repository at this point in the history
  • Loading branch information
eregon committed Sep 12, 2017
1 parent bfa3d67 commit 9018e75
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 2 deletions.
2 changes: 1 addition & 1 deletion lib/drb/extservm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def invoke_service_command(name, command)
pid = spawn("#{command} #{uri} #{name}")
end
th = Process.detach(pid)
th[:drb_service] = name
# th[:drb_service] = name
th
end
end
Expand Down
4 changes: 3 additions & 1 deletion process.c
Original file line number Diff line number Diff line change
Expand Up @@ -1093,11 +1093,13 @@ detach_process_watcher(void *arg)
return rb_last_status_get();
}

VALUE rb_thread_local_aset_no_check(VALUE thread, ID id, VALUE val);

VALUE
rb_detach_process(rb_pid_t pid)
{
VALUE watcher = rb_thread_create(detach_process_watcher, (void*)(VALUE)pid);
rb_thread_local_aset(watcher, id_pid, PIDT2NUM(pid));
rb_thread_local_aset_no_check(watcher, id_pid, PIDT2NUM(pid));
RBASIC_SET_CLASS(watcher, rb_cWaiter);
return watcher;
}
Expand Down
7 changes: 7 additions & 0 deletions test/ruby/test_fiber.rb
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,13 @@ def tvar(var, val)
assert_equal(nil, Thread.current[:v]);
end

def test_inter_thread_tls
t = Thread.new { }
assert_raise(ThreadError) do
t[:foo] = "bar"
end
end

def test_alive
fib = Fiber.new{Fiber.yield}
assert_equal(true, fib.alive?)
Expand Down
7 changes: 7 additions & 0 deletions test/ruby/test_thread.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,13 @@ def test_thread_variable_frozen
end
end

def test_inter_thread_variable
t = Thread.new { }
assert_raise(ThreadError) do
t.thread_variable_set(:foo, "bar")
end
end

def test_mutex_synchronize
m = Thread::Mutex.new
r = 0
Expand Down
18 changes: 18 additions & 0 deletions thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -3149,6 +3149,20 @@ rb_thread_local_aset(VALUE thread, ID id, VALUE val)
rb_error_frozen("thread locals");
}

if (thread != GET_THREAD()->self) {
rb_raise(rb_eThreadError, "inter-thread access of TLS prohibited");
}

return threadptr_local_aset(rb_thread_ptr(thread), id, val);
}

VALUE
rb_thread_local_aset_no_check(VALUE thread, ID id, VALUE val)
{
if (OBJ_FROZEN(thread)) {
rb_error_frozen("thread locals");
}

return threadptr_local_aset(rb_thread_ptr(thread), id, val);
}

Expand Down Expand Up @@ -3226,6 +3240,10 @@ rb_thread_variable_set(VALUE thread, VALUE id, VALUE val)
rb_error_frozen("thread locals");
}

if (thread != GET_THREAD()->self) {
rb_raise(rb_eThreadError, "inter-thread access of TLS prohibited");
}

locals = rb_ivar_get(thread, id_locals);
return rb_hash_aset(locals, rb_to_symbol(id), val);
}
Expand Down

0 comments on commit 9018e75

Please sign in to comment.