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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +16 -0
- data/lib/bwrap/args/args.rb +36 -1
- data/lib/bwrap/args/bind/library/ruby_binds.rb +45 -0
- data/lib/bwrap/args/bind/library.rb +25 -51
- data/lib/bwrap/args/bind/mime.rb +9 -2
- data/lib/bwrap/args/bind.rb +28 -16
- data/lib/bwrap/args/construct.rb +80 -42
- data/lib/bwrap/args/features/binds_base.rb +13 -0
- data/lib/bwrap/args/features/ruby_binds.rb +47 -0
- data/lib/bwrap/args/features.rb +11 -43
- data/lib/bwrap/args/library.rb +1 -3
- data/lib/bwrap/args/mount.rb +5 -5
- data/lib/bwrap/args/network.rb +43 -0
- data/lib/bwrap/bwrap.rb +9 -2
- data/lib/bwrap/config/features/base.rb +28 -0
- data/lib/bwrap/config/features/ruby.rb +86 -0
- data/lib/bwrap/config/features.rb +6 -78
- data/lib/bwrap/execution/exceptions.rb +12 -0
- data/lib/bwrap/execution/execute.rb +21 -3
- data/lib/bwrap/execution/execution.rb +26 -2
- data/lib/bwrap/execution/path.rb +3 -3
- data/lib/bwrap/execution/popen2e.rb +87 -0
- data/lib/bwrap/output/levels.rb +33 -3
- data/lib/bwrap/output/output_impl.rb +54 -0
- data/lib/bwrap/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +39 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 352b23610ac14344695cc17c4bcdaeaf7307b3742983f520581251b4bb7f85a5
|
4
|
+
data.tar.gz: e4cfa7fb8ca749e5dfddf11f6eb030fd82af1bd2a15dad5062d9ba4fd9be72fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/bwrap/args/args.rb
CHANGED
@@ -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
|
-
#
|
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.
|
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
|
-
#
|
58
|
+
# Checks the command given to {Bwrap#run} and adds the libraries it needs.
|
93
59
|
#
|
94
|
-
#
|
95
|
-
def
|
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.
|
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
|
-
|
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.
|
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
|
data/lib/bwrap/args/bind/mime.rb
CHANGED
@@ -22,12 +22,13 @@ class Bwrap::Args::Bind
|
|
22
22
|
@executable_path = executable_path
|
23
23
|
end
|
24
24
|
|
25
|
-
#
|
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
|
-
|
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
|
data/lib/bwrap/args/bind.rb
CHANGED
@@ -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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
data/lib/bwrap/args/construct.rb
CHANGED
@@ -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
|
-
|
29
|
-
|
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.
|
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.
|
51
|
-
share_net
|
52
|
-
hostname
|
53
|
-
@args.
|
54
|
-
@args.
|
55
|
-
@args.
|
56
|
-
|
57
|
-
|
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.
|
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.
|
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.
|
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,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
|