Module: ExecSandbox::Spawn
- Defined in:
- lib/exec_sandbox/spawn.rb
Overview
Manages sandboxed processes.
Defined Under Namespace
Class Method Summary collapse
-
._setrlimit(limit, value) ⇒ Object
Wrapper for Process.setrlimit that eats exceptions.
-
.limit_io(io) ⇒ Object
Constraints the available file descriptors.
-
.limit_resources(limits) ⇒ Object
Constrains the resource usage of the current process.
-
.set_principal(principal) ⇒ Object
Sets the process’ principal for access control.
-
.spawn(command, io = {}, principal = {}, resources = {}) ⇒ Fixnum
Spawns a child process.
Class Method Details
._setrlimit(limit, value) ⇒ Object
Wrapper for Process.setrlimit that eats exceptions.
147 148 149 150 151 152 153 |
# File 'lib/exec_sandbox/spawn.rb', line 147 def self._setrlimit(limit, value) begin Process.setrlimit limit, value, value rescue Errno::EPERM # The call failed, probably because the limit is already lower than this. end end |
.limit_io(io) ⇒ Object
Constraints the available file descriptors.
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/exec_sandbox/spawn.rb', line 30 def self.limit_io(io) # Sort the list of redirections by file descriptor number. redirects = [] [:in, :out, :err].each_with_index do |sym, fd_num| if target = io[sym] redirects << [fd_num, redirects.length, target] end end io.each do |k, v| if k.kind_of? Integer redirects << [k, redirects.length, v] end end # Perform the redirections. redirects.sort! redirects.each do |fd_num, _, target| if target.respond_to?(:fileno) # IO stream. if target.fileno != fd_num LibC.close fd_num LibC.dup2 target.fileno, fd_num end else # Filename string. LibC.close fd_num open_fd = IO.sysopen(target, 'r+') if open_fd != fd_num LibC.dup2 open_fd, fd_num LibC.close open_fd end end end # Close all file descriptors not in the redirection table. redirected_fds = Set.new redirects.map(&:first) max_fd = LibC.getdtablesize max_fd.downto 0 do |fd| next if redirected_fds.include?(fd) next if RubyVM.rb_reserved_fd_p(fd) != 0 LibC.close fd end end |
.limit_resources(limits) ⇒ Object
Constrains the resource usage of the current process.
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/exec_sandbox/spawn.rb', line 124 def self.limit_resources(limits) if limits[:cpu] _setrlimit Process::RLIMIT_CPU, limits[:cpu] end if limits[:processes] _setrlimit Process::RLIMIT_NPROC, limits[:processes] end if limits[:file_size] _setrlimit Process::RLIMIT_FSIZE, limits[:file_size] end if limits[:open_files] _setrlimit Process::RLIMIT_NOFILE, limits[:open_files] end if limits[:data] _setrlimit Process::RLIMIT_AS, limits[:data] _setrlimit Process::RLIMIT_DATA, limits[:data] _setrlimit Process::RLIMIT_STACK, limits[:data] _setrlimit Process::RLIMIT_MEMLOCK, limits[:data] _setrlimit Process::RLIMIT_RSS, limits[:data] end end |
.set_principal(principal) ⇒ Object
Sets the process’ principal for access control.
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/exec_sandbox/spawn.rb', line 81 def self.set_principal(principal) Dir.chdir principal[:dir] if principal[:dir] if principal[:gid] begin Process::Sys.setresgid principal[:gid], principal[:gid], principal[:gid] rescue NotImplementedError Process::Sys.setgid principal[:gid] end end if principal[:uid] begin Process.initgroups Etc.getpwuid(principal[:uid]).name, principal[:gid] || Process.gid rescue NotImplementedError end begin Process::Sys.setresuid principal[:uid], principal[:uid], principal[:uid] rescue NotImplementedError Process::Sys.setuid principal[:uid] end end end |
.spawn(command, io = {}, principal = {}, resources = {}) ⇒ Fixnum
Spawns a child process.
13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/exec_sandbox/spawn.rb', line 13 def self.spawn(command, io = {}, principal = {}, resources = {}) fork do limit_io io limit_resources resources set_principal principal if command.respond_to? :to_str Process.exec command else Process.exec *command end end end |