Skip to content

Commit e82a36f

Browse files
committed
(PUP-11594) Handle misconfigured /proc filesystems in safe_posix_fork
If `/proc/self` is not a directory, `safe_posix_fork` will raise an unhandled `Errno::ENOTDIR`, which will cause all puppet executions to fail. This adds `Errno::ENOTDIR` to the `rescue`, to handle this case.
1 parent 1bac454 commit e82a36f

File tree

2 files changed

+12
-2
lines changed

2 files changed

+12
-2
lines changed

lib/puppet/util.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,7 @@ def safe_posix_fork(stdin=$stdin, stdout=$stdout, stderr=$stderr, &block)
530530
IO::new(f.to_i).close rescue nil
531531
end
532532
end
533-
rescue Errno::ENOENT # /proc/self/fd not found
533+
rescue Errno::ENOENT, Errno::ENOTDIR # /proc/self/fd not found, /proc/self not a dir
534534
3.upto(256){|fd| IO::new(fd).close rescue nil}
535535
end
536536

spec/unit/util_spec.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ def withenv_utf8(&block)
625625
Puppet::Util.safe_posix_fork
626626
end
627627

628-
it "should close all open file descriptors except stdin/stdout/stderr when /proc/self/fd doesn't exists" do
628+
it "should close all open file descriptors except stdin/stdout/stderr when /proc/self/fd doesn't exist" do
629629
# This is ugly, but I can't really think of a better way to do it without
630630
# letting it actually close fds, which seems risky
631631
(0..2).each {|n| expect(IO).not_to receive(:new).with(n)}
@@ -635,6 +635,16 @@ def withenv_utf8(&block)
635635
Puppet::Util.safe_posix_fork
636636
end
637637

638+
it "should close all open file descriptors except stdin/stdout/stderr when /proc/self is not a directory" do
639+
# This is ugly, but I can't really think of a better way to do it without
640+
# letting it actually close fds, which seems risky
641+
(0..2).each {|n| expect(IO).not_to receive(:new).with(n)}
642+
(3..256).each {|n| expect(IO).to receive(:new).with(n).and_return(double('io', close: nil)) }
643+
allow(Dir).to receive(:foreach).with('/proc/self/fd').and_raise(Errno::ENOTDIR)
644+
645+
Puppet::Util.safe_posix_fork
646+
end
647+
638648
it "should fork a child process to execute the block" do
639649
expect(Kernel).to receive(:fork).and_return(pid).and_yield
640650

0 commit comments

Comments
 (0)