Low severityNVD Advisory· Published Mar 3, 2010· Updated Apr 29, 2026
CVE-2010-0156
CVE-2010-0156
Description
Puppet 0.24.x before 0.24.9 and 0.25.x before 0.25.2 allows local users to overwrite arbitrary files via a symlink attack on the (1) /tmp/daemonout, (2) /tmp/puppetdoc.txt, (3) /tmp/puppetdoc.tex, or (4) /tmp/puppetdoc.aux temporary file.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
puppetRubyGems | >= 0.24.0, < 0.24.9 | 0.24.9 |
puppetRubyGems | >= 0.25.0, < 0.25.2 | 0.25.2 |
Affected products
20cpe:2.3:a:puppet:puppet:0.24.3:*:*:*:*:*:*:*+ 19 more
- cpe:2.3:a:puppet:puppet:0.24.3:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.24.4:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.24.5:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.24.6:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.24.6:rc1:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.24.6:rc2:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.24.7:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.24.7:rc2:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.24.8:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.24.8:rc1:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.0:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.0:beta1:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.0:beta2:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.0:rc1:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.1:*:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.1:rc1:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.1:rc2:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.2:rc1:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.2:rc2:*:*:*:*:*:*
- cpe:2.3:a:puppet:puppet:0.25.2:rc3:*:*:*:*:*:*
Patches
20aae57f91dc6Backport of tmpfile patch from 0.25.2
3 files changed · +26 −4
lib/puppet/daemon.rb+1 −1 modified@@ -30,7 +30,7 @@ def daemonize $stderr.reopen $stdout Puppet::Util::Log.reopen rescue => detail - File.open("/tmp/daemonout", "w") { |f| + Puppet::Util.secure_open("/tmp/daemonout", "w") { |f| f.puts "Could not start %s: %s" % [Puppet[:name], detail] } Puppet.err "Could not start %s: %s" % [Puppet[:name], detail]
lib/puppet/util.rb+22 −1 modified@@ -429,7 +429,28 @@ def thinmark end module_function :memory, :thinmark -end + + def secure_open(file,must_be_w,&block) + raise Puppet::DevError,"secure_open only works with mode 'w'" unless must_be_w == 'w' + raise Puppet::DevError,"secure_open only requires a block" unless block_given? + Puppet.warning "#{file} was a symlink to #{File.readlink(file)}" if File.symlink?(file) + if File.exists?(file) or File.symlink?(file) + wait = File.symlink?(file) ? 5.0 : 0.1 + File.delete(file) + sleep wait # give it a chance to reappear, just in case someone is actively trying something. + end + begin + File.open(file,File::CREAT|File::EXCL|File::TRUNC|File::WRONLY,&block) + rescue Errno::EEXIST + desc = File.symlink?(file) ? "symlink to #{File.readlink(file)}" : File.stat(file).ftype + puts "Warning: #{file} was apparently created by another process (as" + puts "a #{desc}) as soon as it was deleted by this process. Someone may be trying" + puts "to do something objectionable (such as tricking you into overwriting system" + puts "files if you are running as root)." + raise + end + end + module_function :secure_open end require 'puppet/util/errors'
lib/puppet/util/reference.rb+3 −2 modified@@ -36,7 +36,7 @@ def self.page(*sections) 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,7 @@ def self.pdf(text) end rst2latex.chomp! cmd = %{#{rst2latex} /tmp/puppetdoc.txt > /tmp/puppetdoc.tex} + Puppet::Util.secure_open('/tmp/puppetdoc.tex','w') {} output = %x{#{cmd}} unless $? == 0 $stderr.puts "rst2latex failed" @@ -168,7 +169,7 @@ def to_trac(with_contents = true) 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
6111ba80f2c6Fix for temporary file security whole
5 files changed · +32 −7
lib/puppet/daemon.rb+2 −2 modified@@ -31,10 +31,10 @@ def daemonize $stderr.reopen $stdout Puppet::Util::Log.reopen rescue => detail - File.open("/tmp/daemonout", "w") { |f| + Puppet.err "Could not start %s: %s" % [Puppet[:name], detail] + Puppet::Util::secure_open("/tmp/daemonout", "w") { |f| f.puts "Could not start %s: %s" % [Puppet[:name], detail] } - Puppet.err "Could not start %s: %s" % [Puppet[:name], detail] exit(12) end end
lib/puppet/network/server.rb+1 −1 modified@@ -22,7 +22,7 @@ def daemonize $stderr.reopen $stdout Puppet::Util::Log.reopen rescue => detail - File.open("/tmp/daemonout", "w") { |f| + Puppet::Util.secure_open("/tmp/daemonout", "w") { |f| f.puts "Could not start %s: %s" % [Puppet[:name], detail] } raise "Could not start %s: %s" % [Puppet[:name], detail]
lib/puppet/rails/benchmark.rb+1 −1 modified@@ -64,6 +64,6 @@ def write_benchmarks data = {} end data[branch] = $benchmarks - File.open(file, "w") { |f| f.print YAML.dump(data) } + Puppet::Util.secure_open(file, "w") { |f| f.print YAML.dump(data) } end end
lib/puppet/util.rb+22 −0 modified@@ -407,6 +407,28 @@ def thinmark end module_function :memory, :thinmark + + def secure_open(file,must_be_w,&block) + raise Puppet::DevError,"secure_open only works with mode 'w'" unless must_be_w == 'w' + raise Puppet::DevError,"secure_open only requires a block" unless block_given? + Puppet.warning "#{file} was a symlink to #{File.readlink(file)}" if File.symlink?(file) + if File.exists?(file) or File.symlink?(file) + wait = File.symlink?(file) ? 5.0 : 0.1 + File.delete(file) + sleep wait # give it a chance to reappear, just in case someone is actively trying something. + end + begin + File.open(file,File::CREAT|File::EXCL|File::TRUNC|File::WRONLY,&block) + rescue Errno::EEXIST + desc = File.symlink?(file) ? "symlink to #{File.readlink(file)}" : File.stat(file).ftype + puts "Warning: #{file} was apparently created by another process (as" + puts "a #{desc}) as soon as it was deleted by this process. Someone may be trying" + puts "to do something objectionable (such as tricking you into overwriting system" + puts "files if you are running as root)." + raise + end + end + module_function :secure_open end end
lib/puppet/util/reference.rb+6 −3 modified@@ -36,7 +36,7 @@ def self.page(*sections) 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 @@ def self.pdf(text) 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 @@ def self.markdown(name, text) 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 @@ def to_trac(with_contents = true) 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
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
14- groups.google.com/group/puppet-announce/browse_thread/thread/4401823f6cbf6087nvdPatchWEB
- secunia.com/advisories/38766nvdPatchVendor Advisory
- bugzilla.redhat.com/show_bug.cginvdPatchWEB
- github.com/advisories/GHSA-vrh7-99jh-3fmmghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2010-0156ghsaADVISORY
- groups.google.com/group/puppet-announce/browse_thread/thread/73cd1b2896d986c2nvdWEB
- lists.fedoraproject.org/pipermail/package-announce/2010-March/036083.htmlnvdWEB
- lists.fedoraproject.org/pipermail/package-announce/2010-March/036166.htmlnvdWEB
- lists.opensuse.org/opensuse-security-announce/2010-06/msg00001.htmlnvdWEB
- github.com/puppetlabs/puppet/commit/0aae57f91dc69b22fb674f8de3a13c22edd07128ghsaWEB
- github.com/puppetlabs/puppet/commit/6111ba80f2c6f6d1541af971f565119e6e03d77dghsaWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/puppet/CVE-2010-0156.ymlghsaWEB
- puppet.com/security/cve/cve-2010-0156nvdWEB
- web.archive.org/web/20100316113904/http://secunia.com/advisories/38766ghsaWEB
News mentions
0No linked articles in our index yet.