Skip to content

Commit 0df08e9

Browse files
committed
(PUP-9997) Don't Dir.chdir when installing modules
When the Dir.chdir block ends we may not have permission to switch our cwd back to where we started. So keep the cwd as is and pass the dest dir to the tar/find/chown commands. Since we're passing arbitrary destination directories, escape it.
1 parent a43942b commit 0df08e9

File tree

2 files changed

+23
-17
lines changed

2 files changed

+23
-17
lines changed

lib/puppet/module_tool/tar/gnu.rb

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,20 @@
44

55
class Puppet::ModuleTool::Tar::Gnu
66
def unpack(sourcefile, destdir, owner)
7-
sourcefile = File.expand_path(sourcefile)
7+
safe_sourcefile = Shellwords.shellescape(File.expand_path(sourcefile))
88
destdir = File.expand_path(destdir)
9+
safe_destdir = Shellwords.shellescape(destdir)
910

10-
Dir.chdir(destdir) do
11-
Puppet::Util::Execution.execute("gzip -dc #{Shellwords.shellescape(sourcefile)} | tar xof -")
12-
Puppet::Util::Execution.execute("find . -type d -exec chmod 755 {} +")
13-
Puppet::Util::Execution.execute("find . -type f -exec chmod u+rw,g+r,a-st {} +")
14-
Puppet::Util::Execution.execute("chown -R #{owner} .")
15-
end
11+
Puppet::Util::Execution.execute("gzip -dc #{safe_sourcefile} | tar --extract --no-same-owner --directory #{safe_destdir} --file -")
12+
Puppet::Util::Execution.execute(['find', destdir, '-type', 'd', '-exec', 'chmod', '755', '{}', '+'])
13+
Puppet::Util::Execution.execute(['find', destdir, '-type', 'f', '-exec', 'chmod', 'u+rw,g+r,a-st', '{}', '+'])
14+
Puppet::Util::Execution.execute(['chown', '-R', owner, destdir])
1615
end
1716

1817
def pack(sourcedir, destfile)
19-
Puppet::Util::Execution.execute("tar cf - #{sourcedir} | gzip -c > #{File.basename(destfile)}")
18+
safe_sourcedir = Shellwords.shellescape(sourcedir)
19+
safe_destfile = Shellwords.shellescape(File.basename(destfile))
20+
21+
Puppet::Util::Execution.execute("tar cf - #{safe_sourcedir} | gzip -c > #{safe_destfile}")
2022
end
2123
end

spec/unit/module_tool/tar/gnu_spec.rb

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
11
require 'spec_helper'
22
require 'puppet/module_tool'
33

4-
describe Puppet::ModuleTool::Tar::Gnu do
4+
describe Puppet::ModuleTool::Tar::Gnu, unless: Puppet::Util::Platform.windows? do
5+
let(:sourcedir) { '/space path/the/src/dir' }
56
let(:sourcefile) { '/space path/the/module.tar.gz' }
67
let(:destdir) { '/space path/the/dest/dir' }
7-
let(:sourcedir) { '/space path/the/src/dir' }
8-
let(:destfile) { '/space path/the/dest/file.tar.gz' }
8+
let(:destfile) { '/space path/the/dest/fi le.tar.gz' }
9+
10+
let(:safe_sourcedir) { '/space\ path/the/src/dir' }
11+
let(:safe_sourcefile) { '/space\ path/the/module.tar.gz' }
12+
let(:safe_destdir) { '/space\ path/the/dest/dir' }
13+
let(:safe_destfile) { 'fi\ le.tar.gz' }
914

1015
it "unpacks a tar file" do
11-
expect(Dir).to receive(:chdir).with(File.expand_path(destdir)).and_yield
12-
expect(Puppet::Util::Execution).to receive(:execute).with("gzip -dc #{Shellwords.shellescape(File.expand_path(sourcefile))} | tar xof -")
13-
expect(Puppet::Util::Execution).to receive(:execute).with("find . -type d -exec chmod 755 {} +")
14-
expect(Puppet::Util::Execution).to receive(:execute).with("find . -type f -exec chmod u+rw,g+r,a-st {} +")
15-
expect(Puppet::Util::Execution).to receive(:execute).with("chown -R <owner:group> .")
16+
expect(Puppet::Util::Execution).to receive(:execute).with("gzip -dc #{safe_sourcefile} | tar --extract --no-same-owner --directory #{safe_destdir} --file -")
17+
expect(Puppet::Util::Execution).to receive(:execute).with(['find', destdir, '-type', 'd', '-exec', 'chmod', '755', '{}', '+'])
18+
expect(Puppet::Util::Execution).to receive(:execute).with(['find', destdir, '-type', 'f', '-exec', 'chmod', 'u+rw,g+r,a-st', '{}', '+'])
19+
expect(Puppet::Util::Execution).to receive(:execute).with(['chown', '-R', '<owner:group>', destdir])
1620
subject.unpack(sourcefile, destdir, '<owner:group>')
1721
end
1822

1923
it "packs a tar file" do
20-
expect(Puppet::Util::Execution).to receive(:execute).with("tar cf - #{sourcedir} | gzip -c > #{File.basename(destfile)}")
24+
expect(Puppet::Util::Execution).to receive(:execute).with("tar cf - #{safe_sourcedir} | gzip -c > #{safe_destfile}")
2125
subject.pack(sourcedir, destfile)
2226
end
2327
end

0 commit comments

Comments
 (0)