bwrap 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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