diff options
author | Markus Roberts <Markus@reality.com> | 2010-01-03 19:04:29 -0800 |
---|---|---|
committer | James Turnbull <james@lovedthanlost.net> | 2010-01-05 17:11:33 +1100 |
commit | 6111ba80f2c6f6d1541af971f565119e6e03d77d (patch) | |
tree | f5d4cc4bed29258ef0ce99822a7cfc184b5252db /lib/puppet/util/reference.rb | |
parent | e7d98ccbc0021bace65dd8525e730462947e5049 (diff) | |
download | puppet-6111ba80f2c6f6d1541af971f565119e6e03d77d.tar.gz puppet-6111ba80f2c6f6d1541af971f565119e6e03d77d.tar.xz puppet-6111ba80f2c6f6d1541af971f565119e6e03d77d.zip |
Fix for temporary file security whole
We create temporary files in /tmp/ with predictable names. These
could be used by an attacker to DoS a box by setting a symlink to
some other file (say, /etc/shadow) and waiting for us to overwrite
it.
The minimalistic solution employed by this patch is to wrap all such
file writing with a paranoid wrapper that:
1) Check to see if the target exists
2) Issues a warning if it was a symlink
3) Deletes it
4) Waits (0.1 seconds if it was a file, 5 seconds if it was a symlink)
5) Opens the file with EXCL, which will fail if the file has come back.
If this succeeds (as it normally will) it has exactly the same semantics
as the original code (a must, as we are right at a release boundary).
However, under no circumstances will it follow a preexisting symlink (the
operating system guarantees this with EXCL) so the danger of an exploit
has been converted into the possibility of a failure, with an appropriate
warning.
Diffstat (limited to 'lib/puppet/util/reference.rb')
-rw-r--r-- | lib/puppet/util/reference.rb | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/lib/puppet/util/reference.rb b/lib/puppet/util/reference.rb index 7526e6566..93542df28 100644 --- a/lib/puppet/util/reference.rb +++ b/lib/puppet/util/reference.rb @@ -36,7 +36,7 @@ class Puppet::Util::Reference def self.pdf(text) puts "creating pdf" - File.open("/tmp/puppetdoc.txt", "w") do |f| + Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f| f.puts text end rst2latex = %x{which rst2latex} @@ -48,6 +48,9 @@ class Puppet::Util::Reference end rst2latex.chomp! cmd = %{#{rst2latex} /tmp/puppetdoc.txt > /tmp/puppetdoc.tex} + Puppet::Util.secure_open("/tmp/puppetdoc.tex","w") do |f| + # If we get here without an error, /tmp/puppetdoc.tex isn't a tricky cracker's symlink + end output = %x{#{cmd}} unless $? == 0 $stderr.puts "rst2latex failed" @@ -67,7 +70,7 @@ class Puppet::Util::Reference puts "Creating markdown for #{name} reference." dir = "/tmp/" + Puppet::PUPPETVERSION FileUtils.mkdir(dir) unless File.directory?(dir) - File.open(dir + "/" + "#{name}.rst", "w") do |f| + Puppet::Util.secure_open(dir + "/" + "#{name}.rst", "w") do |f| f.puts text end pandoc = %x{which pandoc} @@ -190,7 +193,7 @@ class Puppet::Util::Reference end def trac - File.open("/tmp/puppetdoc.txt", "w") do |f| + Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f| f.puts self.to_trac end |