VYPR
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.

PackageAffected versionsPatched versions
puppetRubyGems
>= 0.24.0, < 0.24.90.24.9
puppetRubyGems
>= 0.25.0, < 0.25.20.25.2

Affected products

20
  • cpe: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

2
0aae57f91dc6

Backport of tmpfile patch from 0.25.2

https://github.com/puppetlabs/puppetMarkus RobertsJan 5, 2010via ghsa
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
     
    
6111ba80f2c6

Fix for temporary file security whole

https://github.com/puppetlabs/puppetMarkus RobertsJan 4, 2010via ghsa
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

News mentions

0

No linked articles in our index yet.