From a15f7dd1fb1148c3d586238ee6907875f2e40379 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Sat, 27 Apr 2019 10:05:26 -0700 Subject: [PATCH] Always mark the string returned by File.realpath as tainted This string can include elements that were not in either string passed to File.realpath, even if one of the strings is an absolute path, due to symlinks: ```ruby Dir.mkdir('b') unless File.directory?('b') File.write('b/a', '') unless File.file?('b/a') File.symlink('b', 'c') unless File.symlink?('c') path = File.realpath('c/a'.untaint, Dir.pwd.untaint) path # "/home/testr/ruby/b/a" path.tainted? # should be true, as 'b' comes from file system ``` [Bug #15803] --- file.c | 2 +- test/ruby/test_file.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/file.c b/file.c index 7ab2f2a026..a04fe538e5 100644 --- a/file.c +++ b/file.c @@ -4270,7 +4270,7 @@ rb_check_realpath_internal(VALUE basedir, VALUE path, enum rb_realpath_mode mode } } - OBJ_INFECT(resolved, unresolved_path); + rb_obj_taint(resolved); RB_GC_GUARD(unresolved_path); RB_GC_GUARD(curdir); return resolved; diff --git a/test/ruby/test_file.rb b/test/ruby/test_file.rb index 5e9574cf32..36c154d36c 100644 --- a/test/ruby/test_file.rb +++ b/test/ruby/test_file.rb @@ -298,7 +298,7 @@ class TestFile < Test::Unit::TestCase assert_predicate(File.realpath(base, dir), :tainted?) base.untaint dir.untaint - assert_not_predicate(File.realpath(base, dir), :tainted?) + assert_predicate(File.realpath(base, dir), :tainted?) assert_predicate(Dir.chdir(dir) {File.realpath(base)}, :tainted?) } end