summaryrefslogtreecommitdiff
path: root/lib/rubygems/package.rb
diff options
context:
space:
mode:
authorDavid Rodríguez <[email protected]>2021-10-06 18:17:37 +0200
committergit <[email protected]>2021-10-10 23:12:47 +0900
commitbbcf8f87ac50be423991ccbb2d83ac09ebecf46a ()
treece9e1153cc80d6c0d5ef0282813f4f637d885d4b /lib/rubygems/package.rb
parenta5289bfa71d85d7c3ab1ebf94237edecd847851b (diff)
[ruby/rubygems] Check safety of packaged symlinks
If we explicitly disallow the creation of symlinks that point to files outside of the destination directory, we can avoid any other safety checks while creating directories, because we can be sure they will always fall under the destination directory as well. https://.com/rubygems/rubygems/commit/555692b8de
-rw-r--r--lib/rubygems/package.rb33
1 files changed, 16 insertions, 17 deletions
@@ -71,6 +71,13 @@ class Gem::Package
end
end
class NonSeekableIO < Error; end
class TooLongFileName < Error; end
@@ -407,6 +414,14 @@ EOM
destination = install_location entry.full_name, destination_dir
FileUtils.rm_rf destination
mkdir_options = {}
@@ -419,7 +434,7 @@ EOM
end
unless directories.include?(mkdir)
- mkdir_p_safe mkdir, mkdir_options, destination_dir, entry.full_name
directories << mkdir
end
@@ -495,22 +510,6 @@ EOM
end
end
- def mkdir_p_safe(mkdir, mkdir_options, destination_dir, file_name)
- destination_dir = File.realpath(File.expand_path(destination_dir))
- parts = mkdir.split(File::SEPARATOR)
- parts.reduce do |path, basename|
- path = File.realpath(path) unless path == ""
- path = File.expand_path(path + File::SEPARATOR + basename)
- lstat = File.lstat path rescue nil
- if !lstat || !lstat.directory?
- unless normalize_path(path).start_with? normalize_path(destination_dir) and (FileUtils.mkdir path, **mkdir_options rescue false)
- raise Gem::Package::PathError.new(file_name, destination_dir)
- end
- end
- path
- end
- end
-
##
# Loads a Gem::Specification from the TarEntry +entry+