bwrap 1.0.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e422d8c89dbcf1a803b89532b1214745f558faceaa5dc997ed2487bf92912010
4
- data.tar.gz: 1e265d4aaeb7e05e2b4ff5d8d5f490afb4be04287c0aaeaedc96abf4f2f1022e
3
+ metadata.gz: 352b23610ac14344695cc17c4bcdaeaf7307b3742983f520581251b4bb7f85a5
4
+ data.tar.gz: e4cfa7fb8ca749e5dfddf11f6eb030fd82af1bd2a15dad5062d9ba4fd9be72fb
5
5
  SHA512:
6
- metadata.gz: 86198210a21a75e373e15341d564fc0941d08066d5272b454b64530e3bcce951f0e402c4a9a9f7e34f60d76fbe72140aabab40637e539ec2ef2412a60ebf0f77
7
- data.tar.gz: 2aa60e671d0e8da2fb2d59cf68bc3043d350b557e16c0b81b8a1e62240f24f2d44dfb143b7fb66ab50bac9e51122865326d2290138b35506cd6a6bdabe2b4402
6
+ metadata.gz: cb7feb42474faa52ab6cce4cafd66daabf20f8490519a0f950885b1347332d38a6c335de40d6db4c7371e9eb0a0a722352d6e4613db3e3df193688ae896c584e
7
+ data.tar.gz: 90892a26e8efddc5112c4fa22bd1b95e8380f1860df1680031549f0addf485b4229fcdd11d786a63d476bf151483db60eba7682d045d35b08dfccea88e6b5f44
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changes
2
2
 
3
+ ## 1.1.1 (07.06.2022)
4
+
5
+ * Added Bwrap::Execution.popen2e
6
+ * Fixed compatibility with ruby-2.5
7
+
8
+ ## 1.1.0 (01.06.2022)
9
+
10
+ * No changes.
11
+
12
+ ## 1.1.0-rc1 (28.05.2022)
13
+
14
+ * Added info log level
15
+ * Added --quiet cli argument
16
+ * Added more command and output to ExecutionFailed exception
17
+ * Use script’s ruby version to load libraries
18
+
3
19
  ## 1.0.0 (16.04.2022)
4
20
 
5
21
  * Handle invalid output to loggers
@@ -8,5 +8,40 @@ require "bwrap/version"
8
8
  # In future, there may be some use for classes inside here, but for now they are
9
9
  # only used internally.
10
10
  module Bwrap::Args
11
- # Nya.
11
+ # Used as container for arguments constructed via {Construct}.
12
+ #
13
+ # Where {Hash} defaults to nil as default argument, `Args` defaults to
14
+ # {Array}.
15
+ class Args < Hash
16
+ # Creates new instance of a hash for storing arguments.
17
+ #
18
+ # Where {Hash} defaults to nil as default argument, `Args` defaults to
19
+ # `[]`.
20
+ #
21
+ # @see Hash#initialize
22
+ def initialize(*args)
23
+ if args.empty? and !block_given?
24
+ super(*args) { [] }
25
+ else
26
+ super(*args)
27
+ end
28
+ end
29
+
30
+ # Adds given data to array identified by given type.
31
+ #
32
+ # Following types are meant to be used, though everything is accepted:
33
+ # - :mount
34
+ #
35
+ # @param type [Symbol] Type of the argument
36
+ # @returns self
37
+ def add(type, *data)
38
+ if data.respond_to? :each
39
+ self[type] += data.flatten
40
+ else
41
+ self[type] << data
42
+ end
43
+
44
+ self
45
+ end
46
+ end
12
47
  end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Ruby feature implementation specific class.
4
+ #
5
+ # @api private
6
+ class Bwrap::Args::Bind::Library::RubyBinds
7
+ # Instance of {Bwrap::Config}.
8
+ attr_writer :config
9
+
10
+ def initialize args
11
+ @args = args
12
+ end
13
+
14
+ def ruby_binds_for_features
15
+ return unless @config and @config.features.ruby.enabled?
16
+
17
+ @mounts = []
18
+
19
+ # Mount some common Ruby executables.
20
+
21
+ # This is most often /usr/bin.
22
+ bindir = Pathname.new @config.features.ruby.ruby_config["bindir"]
23
+
24
+ bind_ruby_executable
25
+ gem_binds bindir
26
+
27
+ @args.add :library_feature_binds, @mounts
28
+ end
29
+
30
+ private def bind_ruby_executable
31
+ path = @config.features.ruby.interpreter
32
+ raise "Ruby interpreter “#{path}” not found." unless File.exist? path
33
+
34
+ @mounts << "--ro-bind" << path.to_s << path.to_s
35
+ end
36
+
37
+ private def gem_binds bindir
38
+ return unless @config.features.ruby.gem_env_paths?
39
+
40
+ path = bindir / "gem"
41
+ return unless File.exist? path
42
+
43
+ @mounts << "--ro-bind" << path.to_s << path.to_s
44
+ end
45
+ end
@@ -13,9 +13,16 @@ class Bwrap::Args::Bind
13
13
  #
14
14
  # @api private
15
15
  class Library
16
+ # Requires are here so there is no extra trickiness with namespaces.
17
+ #
18
+ # Feature implementations are not meant to be used outside of this class anyway.
19
+ require_relative "library/ruby_binds"
20
+
16
21
  include Bwrap::Execution::Path
17
22
  include Bwrap::Output
18
23
 
24
+ # The command given to {Bwrap#run}.
25
+ #
19
26
  # @see Bwrap::Args::Construct#command=
20
27
  #
21
28
  # @see (see Bwrap::Args::Construct#command=)
@@ -31,47 +38,6 @@ class Bwrap::Args::Bind
31
38
 
32
39
  attr_writer :executable_path
33
40
 
34
- # Ruby feature implementation specific class.
35
- #
36
- # @api private
37
- class RubyBinds
38
- # Instance of {Bwrap::Config}.
39
- attr_writer :config
40
-
41
- def initialize args
42
- @args = args
43
- end
44
-
45
- def ruby_binds_for_features
46
- return unless @config and @config.features.ruby.enabled?
47
-
48
- @mounts = []
49
-
50
- # Mount some common Ruby executables.
51
-
52
- # This is most often /usr/bin.
53
- bindir = Pathname.new RbConfig::CONFIG["bindir"]
54
-
55
- path = bindir / "ruby"
56
- if File.exist? path
57
- @mounts << "--ro-bind" << path.to_s << path.to_s
58
- end
59
-
60
- gem_binds bindir
61
-
62
- @args += @mounts
63
- end
64
-
65
- private def gem_binds bindir
66
- return unless @config.features.ruby.gem_env_paths?
67
-
68
- path = bindir / "gem"
69
- return unless File.exist? path
70
-
71
- @mounts << "--ro-bind" << path.to_s << path.to_s
72
- end
73
- end
74
-
75
41
  def initialize args
76
42
  @args = args
77
43
  end
@@ -83,22 +49,22 @@ class Bwrap::Args::Bind
83
49
  @executable_name = resolve_executable_name executable
84
50
  @executable_path = resolve_executable_path @executable_name, not_inside_root: true
85
51
 
86
- @args.append %W{ --ro-bind #{@executable_path} #{@executable_path} }
52
+ @args.add :extra_executable_mounts, %W{ --ro-bind #{@executable_path} #{@executable_path} }
87
53
 
88
54
  resolve_executable_libraries
89
55
  end
90
56
  end
91
57
 
92
- # Convenience method to call {#resolve_executable_libraries}.
58
+ # Checks the command given to {Bwrap#run} and adds the libraries it needs.
93
59
  #
94
- # Used by {#handle_system_mounts}.
95
- def libs_command_requires
60
+ # Convenience method to call {#resolve_executable_libraries}.
61
+ def handle_given_command
96
62
  @executable_name = resolve_executable_name @command
97
63
  @executable_path = resolve_executable_path @executable_name
98
64
 
99
65
  # Actually add the executable to be bound to the sandbox.
100
66
  unless @config&.command_inside_root
101
- @args.append %W{ --ro-bind #{@executable_path} #{@executable_path} }
67
+ @args.add :given_command, %W{ --ro-bind #{@executable_path} #{@executable_path} }
102
68
  end
103
69
 
104
70
  resolve_executable_libraries
@@ -112,7 +78,7 @@ class Bwrap::Args::Bind
112
78
  # @todo Ensure scanelf is available (and throw proper error if it is not, telling to not use
113
79
  # full_system_mounts option.)
114
80
  def resolve_executable_libraries
115
- trace "Resolving executable libraries of #{@executable_path}"
81
+ debug "Resolving executable libraries of #{@executable_path}"
116
82
 
117
83
  # TODO: Put this behind additional flag for extra control/sanity.
118
84
  # Some executables are shell scripts and similar. For them we need to use the interpreter.
@@ -120,6 +86,17 @@ class Bwrap::Args::Bind
120
86
  mime = Mime.new @executable_name, @executable_path
121
87
  return unless mime.resolve_mime_type
122
88
 
89
+ # TODO: Ideally mime stuff should be handled as config,
90
+ # but then shebang parsing logic would be necessary to move to config classes.
91
+ #
92
+ # That may make sense, but for now this is here.
93
+ #
94
+ # This basically allows features to use mime data to get for example path to necessary interpreter.
95
+ #
96
+ # This way there is possibility that wrong mime information would be used,
97
+ # as this thing is more generalized.
98
+ @config.features.mime = mime if @config&.features
99
+
123
100
  # Then find out required libraries
124
101
 
125
102
  library_mounts = []
@@ -133,7 +110,7 @@ class Bwrap::Args::Bind
133
110
  library_mounts << "--ro-bind" << library << library
134
111
  end
135
112
 
136
- @args.append library_mounts
113
+ @args.add :extra_executable_libraries, library_mounts
137
114
  end
138
115
 
139
116
  # Some features, like {Bwrap::Config::Features::Nscd}, requires some binds
@@ -147,7 +124,6 @@ class Bwrap::Args::Bind
147
124
  ruby_binds_for_features
148
125
  end
149
126
 
150
- # Used by {#libs_command_requires}.
151
127
  private def resolve_executable_name command
152
128
  if command.is_a? String
153
129
  return command
@@ -162,8 +138,6 @@ class Bwrap::Args::Bind
162
138
  end
163
139
 
164
140
  # @warning Requires environment paths to be resolved beforehand.
165
- #
166
- # Used by {#libs_command_requires}.
167
141
  private def resolve_executable_path executable_name, not_inside_root: nil
168
142
  if @config&.command_inside_root.nil? or not_inside_root
169
143
  return which executable_name
@@ -22,12 +22,13 @@ class Bwrap::Args::Bind
22
22
  @executable_path = executable_path
23
23
  end
24
24
 
25
- # Used by {Bwrap::Args::Bind::Library#libs_command_requires}.
25
+ # Checks if target executable is a script, in which case executable
26
+ # is parsed from a shebang line, if found.
26
27
  #
27
28
  # @return false if caller should also return
28
29
  def resolve_mime_type
29
30
  mime_type = execvalue %W{ file --brief --mime-type #{@executable_path} }
30
- trace "Mime type of #{@executable_path} is #{mime_type}"
31
+ debug "Mime type of #{@executable_path} is #{mime_type}"
31
32
  return true unless mime_type[0..6] == "text/x-"
32
33
 
33
34
  shebang = File.open @executable_path, &:readline
@@ -42,7 +43,11 @@ class Bwrap::Args::Bind
42
43
  true
43
44
  end
44
45
 
46
+ # Parses shebang line to find out path to actual executable
47
+ # used to run the script.
45
48
  private def resolve_real_executable shebang
49
+ #trace "Figuring out correct executable from shebang #{shebang}"
50
+
46
51
  command_line = shebang.delete_prefix("#!").strip
47
52
  real_executable, args = command_line.split " ", 2
48
53
 
@@ -52,6 +57,8 @@ class Bwrap::Args::Bind
52
57
  real_executable = which executable_name
53
58
  end
54
59
 
60
+ debug "Parsed #{real_executable} from the script’s shebang. Using as executable."
61
+
55
62
  @executable_path = real_executable
56
63
  end
57
64
  end
@@ -13,6 +13,8 @@ class Bwrap::Args::Bind
13
13
  # Array of parameters passed to bwrap.
14
14
  attr_writer :args
15
15
 
16
+ # The command given to {Bwrap#run}.
17
+ #
16
18
  # @see Bwrap::Args::Construct#command=
17
19
  #
18
20
  # @see (see Bwrap::Args::Construct#command=)
@@ -26,17 +28,17 @@ class Bwrap::Args::Bind
26
28
 
27
29
  # Arguments to bind /dev/dri from host to sandbox.
28
30
  def bind_dev_dri
29
- @args.append %w{ --dev-bind /dev/dri /dev/dri }
31
+ @args.add :dev_mounts, %w{ --dev-bind /dev/dri /dev/dri }
30
32
  end
31
33
 
32
34
  # Arguments to bind /sys/dev/char from host to sandbox.
33
35
  def bind_sys_dev_char
34
- @args.append %w{ --ro-bind /sys/dev/char /sys/dev/char }
36
+ @args.add :dev_mounts, %w{ --ro-bind /sys/dev/char /sys/dev/char }
35
37
  end
36
38
 
37
39
  # Arguments to bind /sys/devices/pci0000:00 from host to sandbox.
38
40
  def bind_pci_devices
39
- @args.append %w{ --ro-bind /sys/devices/pci0000:00 /sys/devices/pci0000:00 }
41
+ @args.add :dev_mounts, %w{ --ro-bind /sys/devices/pci0000:00 /sys/devices/pci0000:00 }
40
42
  end
41
43
 
42
44
  # Arguments to bind home directory from sandbox directory (`#{@config.sandbox_directory}/home`)
@@ -55,7 +57,23 @@ class Bwrap::Args::Bind
55
57
  @environment["HOME"] = "/home/#{@config.user}"
56
58
 
57
59
  debug "Using #{home_directory} as /home/#{@config.user}"
58
- @args.append %W{ --bind #{home_directory} /home/#{@config.user} }
60
+ @args.add :home_directory, %W{ --bind #{home_directory} /home/#{@config.user} }
61
+ end
62
+
63
+ # Handle command passed to Bwrap#run.
64
+ #
65
+ # Allows subsequent actions to utilize the command.
66
+ def handle_given_command
67
+ construct_library_bind
68
+
69
+ # I’m not completely sure this is a good idea. Maybe only dependent libraries
70
+ # should be skipped and the actual executable should still be checked?
71
+ #
72
+ # Or maybe the data should be calculated and these are excluded in
73
+ # Construct#bwrap_arguments?
74
+ return unless @config.full_system_mounts
75
+
76
+ @library_bind.handle_given_command
59
77
  end
60
78
 
61
79
  # Arguments to read-only bind whole system inside sandbox.
@@ -67,7 +85,7 @@ class Bwrap::Args::Bind
67
85
  end
68
86
  @environment.add_to_path binaries_from
69
87
 
70
- @args.append bindir_mounts
88
+ @args.add :bindir, bindir_mounts
71
89
 
72
90
  if debug?
73
91
  debug "Using following bindir mounts:\n" \
@@ -77,15 +95,9 @@ class Bwrap::Args::Bind
77
95
 
78
96
  libdir_mounts
79
97
 
80
- library_bind = construct_library_bind
81
-
82
98
  binds_for_features
83
- library_bind.binds_for_features
84
- library_bind.extra_executables_mounts
85
-
86
- return unless @config.full_system_mounts
87
-
88
- library_bind.libs_command_requires
99
+ @library_bind.binds_for_features
100
+ @library_bind.extra_executables_mounts
89
101
  end
90
102
 
91
103
  # These are something user can specify to do custom --ro-bind binds.
@@ -97,7 +109,7 @@ class Bwrap::Args::Bind
97
109
  binds << "--ro-bind" << source_path.to_s << destination_path.to_s
98
110
  end
99
111
 
100
- @args.append binds unless binds.empty?
112
+ @args.add :custom_ro_binds, binds unless binds.empty?
101
113
  end
102
114
 
103
115
  # Performs cleanup operations after execution.
@@ -122,7 +134,7 @@ class Bwrap::Args::Bind
122
134
  "(Odd is key, even is value)"
123
135
  end
124
136
 
125
- @args.append libdir_mounts
137
+ @args.add :libdir, libdir_mounts
126
138
  end
127
139
 
128
140
  private def construct_library_bind
@@ -131,7 +143,7 @@ class Bwrap::Args::Bind
131
143
  library_bind.config = @config
132
144
  library_bind.environment = @environment
133
145
 
134
- library_bind
146
+ @library_bind = library_bind
135
147
  end
136
148
 
137
149
  # Binds feature specific common directories.
@@ -3,11 +3,13 @@
3
3
  require "tempfile"
4
4
 
5
5
  require "bwrap/output"
6
+ require_relative "args"
6
7
  require_relative "bind"
7
8
  require_relative "environment"
8
9
  require_relative "features"
9
10
  require_relative "machine_id"
10
11
  require_relative "mount"
12
+ require_relative "network"
11
13
 
12
14
  # Constructs arguments for bwrap execution.
13
15
  class Bwrap::Args::Construct
@@ -25,16 +27,27 @@ class Bwrap::Args::Construct
25
27
  # @param value [Array, String] Command with arguments
26
28
  attr_writer :command
27
29
 
28
- # Constructs arguments for bwrap execution.
29
- def construct_bwrap_args
30
- @args = []
30
+ def initialize
31
+ # If a key is not found, it is initialized with an empty array.
32
+ @args = Bwrap::Args::Args.new
33
+ end
34
+
35
+ # Parses data given with {Config} so it can be outputted in proper
36
+ # order by {#bwrap_arguments}.
37
+ #
38
+ # @note Command given to {Bwrap#run} is set to {Bind#command}.
39
+ def calculate
31
40
  create_objects
32
41
 
42
+ # If necessary, first handle command passed to Bwrap#run so feature binds can utilize
43
+ # the command.
44
+ @bind.handle_given_command
45
+
33
46
  root_mount
34
47
  xauthority_args
35
48
  machine_id = @machine_id.machine_id
36
- @args.append machine_id if machine_id
37
- resolv_conf
49
+ @args.add :machine_id, machine_id if machine_id
50
+ @network.resolv_conf
38
51
  @bind.handle_system_mounts
39
52
  @features.feature_binds
40
53
  @bind.custom_read_only_binds
@@ -47,14 +60,62 @@ class Bwrap::Args::Construct
47
60
  proc_mount
48
61
  tmp_as_tmpfs
49
62
  @bind.bind_home_directory
50
- @args.append "--unshare-all"
51
- share_net
52
- hostname
53
- @args.append @environment.environment_variables
54
- @args.append "--die-with-parent"
55
- @args.append "--new-session"
56
-
57
- @args.compact
63
+ @args.add :unshare_all, "--unshare-all" # Practically means that there would be nothing in the sandbox by default.
64
+ @network.share_net
65
+ @network.hostname
66
+ @args.add :environment, @environment.environment_variables
67
+ @args.add :die_with_parent, "--die-with-parent" # For security, and as intuition says how things should work.
68
+ @args.add :new_session, "--new-session" # Very important for security.
69
+ end
70
+
71
+ # Returns arguments to pass to bwrap.
72
+ #
73
+ # @note Command given to {Bwrap#run} is set to {Bind#command}.
74
+ def bwrap_arguments
75
+ args = []
76
+
77
+ # @args.fetch() could be used here to ensure the key is present, so catching some extra typos,
78
+ # but for now it is not used, for convenience.
79
+
80
+ args += @args[:root_mount]
81
+ args += @args[:xauthority]
82
+ args += @args[:machine_id]
83
+ args += @args[:resolv_conf]
84
+
85
+ # bind.rb
86
+ args += @args[:bindir]
87
+ args += @args[:libdir]
88
+
89
+ # This is what is given to Bwrap#run.
90
+ args += @args[:given_command]
91
+
92
+ args += @args[:extra_executable_libraries]
93
+ args += @args[:library_feature_binds]
94
+ args += @args[:extra_executable_mounts]
95
+
96
+ args += @args[:feature_binds]
97
+
98
+ args += @args[:custom_ro_binds]
99
+ args += @args[:user_dir]
100
+
101
+ args += @args[:audio]
102
+ args += @args[:dev_mounts]
103
+ args += @args[:proc_mount]
104
+ args += @args[:tmp_mount]
105
+
106
+ args += @args[:home_directory]
107
+
108
+ args += @args[:unshare_all]
109
+
110
+ args += @args[:network]
111
+
112
+ args += @args[:hostname]
113
+ args += @args[:environment]
114
+
115
+ args += @args[:die_with_parent]
116
+ args += @args[:new_session]
117
+
118
+ args.compact
58
119
  end
59
120
 
60
121
  # Performs cleanup operations after execution.
@@ -80,6 +141,9 @@ class Bwrap::Args::Construct
80
141
 
81
142
  @machine_id = Bwrap::Args::MachineId.new
82
143
  @machine_id.config = @config
144
+
145
+ @network = Bwrap::Args::Network.new @args
146
+ @network.config = @config
83
147
  end
84
148
 
85
149
  # Arguments for generating .Xauthority file.
@@ -88,23 +152,13 @@ class Bwrap::Args::Construct
88
152
 
89
153
  xauth_args = %W{ --ro-bind #{Dir.home}/.Xauthority #{Dir.home}/.Xauthority }
90
154
  debug "Binding following .Xauthority file: #{Dir.home}/.Xauthority"
91
- @args.append xauth_args
92
- end
93
-
94
- # Arguments to read-only bind /etc/resolv.conf.
95
- private def resolv_conf
96
- # We can’t really bind symlinks, so let’s resolve real path to resolv.conf, in case it is symlinked.
97
- source_resolv_conf = Pathname.new "/etc/resolv.conf"
98
- source_resolv_conf = source_resolv_conf.realpath
99
-
100
- debug "Binding #{source_resolv_conf} as /etc/resolv.conf"
101
- @args.append %W{ --ro-bind #{source_resolv_conf} /etc/resolv.conf }
155
+ @args.add :xauthority, xauth_args
102
156
  end
103
157
 
104
158
  # Arguments to create `/run/user/#{uid}`.
105
159
  private def create_user_dir
106
160
  trace "Creating directory /run/user/#{uid}"
107
- @args.append %W{ --dir /run/user/#{uid} }
161
+ @args.add :user_dir, %W{ --dir /run/user/#{uid} }
108
162
  end
109
163
 
110
164
  # Arguments to bind necessary pulseaudio data for audio support.
@@ -112,23 +166,7 @@ class Bwrap::Args::Construct
112
166
  return unless @config.audio.include? :pulseaudio
113
167
 
114
168
  debug "Binding pulseaudio"
115
- @args.append %W{ --ro-bind /run/user/#{uid}/pulse /run/user/#{uid}/pulse }
116
- end
117
-
118
- # Arguments to allow network connection inside sandbox.
119
- private def share_net
120
- return unless @config.share_net
121
-
122
- verb "Sharing network"
123
- @args.append %w{ --share-net }
124
- end
125
-
126
- # Arguments to set hostname to whatever is configured.
127
- private def hostname
128
- return unless @config.hostname
129
-
130
- debug "Setting hostname to #{@config.hostname}"
131
- @args.append %W{ --hostname #{@config.hostname} }
169
+ @args.add :audio, %W{ --ro-bind /run/user/#{uid}/pulse /run/user/#{uid}/pulse }
132
170
  end
133
171
 
134
172
  # Returns current user id.
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @abstract
4
+ #
5
+ # Base class for binds.
6
+ #
7
+ # @api private
8
+ class Bwrap::Args::Features::BindsBase
9
+ # @param config [Config] Instance of Config.
10
+ def initialize config
11
+ @config = config
12
+ end
13
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Implementation for Ruby feature set.
4
+ #
5
+ # @api private
6
+ class Bwrap::Args::Features::RubyBinds < Bwrap::Args::Features::BindsBase
7
+ # Returns mounts needed by Ruby feature set.
8
+ attr_reader :mounts
9
+
10
+ # Bind system paths so scripts works inside sandbox.
11
+ def sitedir_mounts
12
+ raise "@config is required" unless @config
13
+
14
+ ruby_config = @config.features.ruby.ruby_config
15
+
16
+ mounts = []
17
+ mounts << "--ro-bind" << ruby_config["sitedir"] << ruby_config["sitedir"]
18
+ mounts << "--ro-bind" << ruby_config["rubyhdrdir"] << ruby_config["rubyhdrdir"]
19
+ mounts << "--ro-bind" << ruby_config["rubylibdir"] << ruby_config["rubylibdir"]
20
+ mounts << "--ro-bind" << ruby_config["vendordir"] << ruby_config["vendordir"]
21
+
22
+ mounts
23
+ end
24
+
25
+ # Create binds for required system libraries.
26
+ #
27
+ # These are in path like /usr/lib64/ruby/2.5.0/x86_64-linux-gnu/,
28
+ # and as they are mostly shared libraries, they may have some extra
29
+ # dependencies that also need to be bound inside the sandbox.
30
+ def stdlib_mounts stdlib
31
+ raise "@config is required" unless @config
32
+
33
+ ruby_config = @config.features.ruby.ruby_config
34
+
35
+ library_mounts = []
36
+ library = Bwrap::Args::Library.new
37
+ stdlib.each do |lib|
38
+ path = "#{ruby_config["rubyarchdir"]}/#{lib}.so"
39
+
40
+ library.needed_libraries(path).each do |requisite_library|
41
+ library_mounts << "--ro-bind" << requisite_library << requisite_library
42
+ end
43
+ end
44
+
45
+ library_mounts
46
+ end
47
+ end