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 +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
|