diff options
author | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2023-08-29 20:04:14 +1200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-29 20:04:14 +1200 |
commit | 901b6d9c5025a30b3d7a5ed0a2c00baf9cfb061d (patch) | |
tree | a7331e00fb79b82e8ecf59bad22c43409e21d704 | |
parent | 141102b0b08c4feb682210033cac8d0f042c4beb (diff) | |
download | ruby-901b6d9c5025a30b3d7a5ed0a2c00baf9cfb061d.tar.gz |
Validate the typed data before dereferencing the internal struct. (#8315)
-rw-r--r-- | process.c | 5 | ||||
-rw-r--r-- | test/fiber/test_process.rb | 21 |
2 files changed, 24 insertions, 2 deletions
@@ -1222,7 +1222,7 @@ rb_waitpid(rb_pid_t pid, int *st, int flags) VALUE status = rb_process_status_wait(pid, flags); if (NIL_P(status)) return 0; - struct rb_process_status *data = RTYPEDDATA_DATA(status); + struct rb_process_status *data = rb_check_typeddata(status, &rb_process_status_type); pid = data->pid; if (st) *st = data->status; @@ -4748,7 +4748,8 @@ rb_f_system(int argc, VALUE *argv, VALUE _) if (pid > 0) { VALUE status = rb_process_status_wait(pid, 0); - struct rb_process_status *data = RTYPEDDATA_DATA(status); + + struct rb_process_status *data = rb_check_typeddata(status, &rb_process_status_type); // Set the last status: rb_obj_freeze(status); diff --git a/test/fiber/test_process.rb b/test/fiber/test_process.rb index a5990be204..cc1694576e 100644 --- a/test/fiber/test_process.rb +++ b/test/fiber/test_process.rb @@ -34,6 +34,27 @@ class TestFiberProcess < Test::Unit::TestCase end.join end + def test_system_faulty_process_wait + Thread.new do + scheduler = Scheduler.new + + def scheduler.process_wait(pid, flags) + Fiber.blocking{Process.wait(pid, flags)} + + # Don't return `Process::Status` instance. + return false + end + + Fiber.set_scheduler scheduler + + Fiber.schedule do + assert_raise TypeError do + system("true") + end + end + end.join + end + def test_fork omit 'fork not supported' unless Process.respond_to?(:fork) Thread.new do |