bwrap 1.0.0.pre.alpha5 → 1.0.0
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 +26 -0
- data/lib/bwrap/args/args.rb +5 -1
- data/lib/bwrap/args/bind/library.rb +188 -0
- data/lib/bwrap/args/bind/mime.rb +58 -0
- data/lib/bwrap/args/bind.rb +27 -89
- data/lib/bwrap/args/construct.rb +3 -2
- data/lib/bwrap/args/environment.rb +59 -1
- data/lib/bwrap/args/features.rb +65 -3
- data/lib/bwrap/args/library.rb +17 -10
- data/lib/bwrap/args/machine_id.rb +6 -3
- data/lib/bwrap/args/mount.rb +1 -0
- data/lib/bwrap/bwrap.rb +151 -0
- data/lib/bwrap/bwrap_module.rb +26 -0
- data/lib/bwrap/config/features.rb +116 -0
- data/lib/bwrap/config.rb +96 -92
- data/lib/bwrap/execution/exceptions.rb +24 -0
- data/lib/bwrap/execution/execute.rb +4 -1
- data/lib/bwrap/execution/execution.rb +147 -3
- data/lib/bwrap/execution/labels.rb +8 -1
- data/lib/bwrap/execution/path.rb +30 -10
- data/lib/bwrap/execution.rb +6 -160
- data/lib/bwrap/output/colors.rb +0 -2
- data/lib/bwrap/output/log.rb +17 -5
- data/lib/bwrap/output/output_impl.rb +182 -0
- data/lib/bwrap/output.rb +8 -152
- data/lib/bwrap/version.rb +1 -2
- data/lib/bwrap.rb +1 -79
- data.tar.gz.sig +0 -0
- metadata +11 -19
- metadata.gz.sig +0 -0
- data/lib/bwrap/output/output.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e422d8c89dbcf1a803b89532b1214745f558faceaa5dc997ed2487bf92912010
|
4
|
+
data.tar.gz: 1e265d4aaeb7e05e2b4ff5d8d5f490afb4be04287c0aaeaedc96abf4f2f1022e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86198210a21a75e373e15341d564fc0941d08066d5272b454b64530e3bcce951f0e402c4a9a9f7e34f60d76fbe72140aabab40637e539ec2ef2412a60ebf0f77
|
7
|
+
data.tar.gz: 2aa60e671d0e8da2fb2d59cf68bc3043d350b557e16c0b81b8a1e62240f24f2d44dfb143b7fb66ab50bac9e51122865326d2290138b35506cd6a6bdabe2b4402
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
# Changes
|
2
2
|
|
3
|
+
## 1.0.0 (16.04.2022)
|
4
|
+
|
5
|
+
* Handle invalid output to loggers
|
6
|
+
|
7
|
+
## 1.0.0-beta2 (02.02.2022)
|
8
|
+
|
9
|
+
* Added nscd feature
|
10
|
+
* Added gem_env_paths to ruby feature
|
11
|
+
* If Config#root is set, set working directory to /
|
12
|
+
* Execution#execvalue: Allow setting log: true
|
13
|
+
* Execution#execvalue: pass all kwargs as kwargs to execute()
|
14
|
+
* Output::Log: Don’t die if log file can’t be written to
|
15
|
+
|
16
|
+
## 1.0.0-beta1 (12.12.2021)
|
17
|
+
|
18
|
+
* optimist gem is now optional dependency
|
19
|
+
* Added Config#env_paths and Config#add_env_path
|
20
|
+
* Added Config#command_inside_root
|
21
|
+
* Added Bwrap#run_inside_root convenience method
|
22
|
+
* Execution#command_available?: added env_path_var argument
|
23
|
+
* Execution#which: added env_path_var argument
|
24
|
+
* Be able to resolve /usr/bin/env to real executable
|
25
|
+
* Try to avoid duplicate library binds
|
26
|
+
* Added Config#extra_executables
|
27
|
+
* Added Config::Features::Bash
|
28
|
+
|
3
29
|
## 1.0.0-alpha5 (29.11.2021)
|
4
30
|
|
5
31
|
* Execution#command_available?: support absolute paths
|
data/lib/bwrap/args/args.rb
CHANGED
@@ -2,7 +2,11 @@
|
|
2
2
|
|
3
3
|
require "bwrap/version"
|
4
4
|
|
5
|
-
#
|
5
|
+
# Classes that are used for building arguments.
|
6
|
+
#
|
7
|
+
# @note Classes inside here are kind of pseudo-internal API.
|
8
|
+
# In future, there may be some use for classes inside here, but for now they are
|
9
|
+
# only used internally.
|
6
10
|
module Bwrap::Args
|
7
11
|
# Nya.
|
8
12
|
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bwrap/execution/path"
|
4
|
+
require "bwrap/output"
|
5
|
+
require_relative "../library"
|
6
|
+
require_relative "mime"
|
7
|
+
|
8
|
+
class Bwrap::Args::Bind
|
9
|
+
# TODO: documentation
|
10
|
+
#
|
11
|
+
# TODO: It may be that this should be renamed to “Binary” or ”Executable”, as this
|
12
|
+
# handles all binaries, not just libraries.
|
13
|
+
#
|
14
|
+
# @api private
|
15
|
+
class Library
|
16
|
+
include Bwrap::Execution::Path
|
17
|
+
include Bwrap::Output
|
18
|
+
|
19
|
+
# @see Bwrap::Args::Construct#command=
|
20
|
+
#
|
21
|
+
# @see (see Bwrap::Args::Construct#command=)
|
22
|
+
attr_writer :command
|
23
|
+
|
24
|
+
# Instance of {Bwrap::Config}.
|
25
|
+
attr_writer :config
|
26
|
+
|
27
|
+
# Instance of {Bwrap::Args::Environment}.
|
28
|
+
attr_writer :environment
|
29
|
+
|
30
|
+
attr_writer :executable_name
|
31
|
+
|
32
|
+
attr_writer :executable_path
|
33
|
+
|
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
|
+
def initialize args
|
76
|
+
@args = args
|
77
|
+
end
|
78
|
+
|
79
|
+
def extra_executables_mounts
|
80
|
+
return unless @config&.extra_executables
|
81
|
+
|
82
|
+
@config.extra_executables.each do |executable|
|
83
|
+
@executable_name = resolve_executable_name executable
|
84
|
+
@executable_path = resolve_executable_path @executable_name, not_inside_root: true
|
85
|
+
|
86
|
+
@args.append %W{ --ro-bind #{@executable_path} #{@executable_path} }
|
87
|
+
|
88
|
+
resolve_executable_libraries
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# Convenience method to call {#resolve_executable_libraries}.
|
93
|
+
#
|
94
|
+
# Used by {#handle_system_mounts}.
|
95
|
+
def libs_command_requires
|
96
|
+
@executable_name = resolve_executable_name @command
|
97
|
+
@executable_path = resolve_executable_path @executable_name
|
98
|
+
|
99
|
+
# Actually add the executable to be bound to the sandbox.
|
100
|
+
unless @config&.command_inside_root
|
101
|
+
@args.append %W{ --ro-bind #{@executable_path} #{@executable_path} }
|
102
|
+
end
|
103
|
+
|
104
|
+
resolve_executable_libraries
|
105
|
+
end
|
106
|
+
|
107
|
+
# Does some inspection to find out libraries given executable needs in order to work.
|
108
|
+
#
|
109
|
+
# @warning scanelf does not play with spaces in names well. This method assumes that libraries
|
110
|
+
# have no spaces in names, though binaries can have.
|
111
|
+
#
|
112
|
+
# @todo Ensure scanelf is available (and throw proper error if it is not, telling to not use
|
113
|
+
# full_system_mounts option.)
|
114
|
+
def resolve_executable_libraries
|
115
|
+
trace "Resolving executable libraries of #{@executable_path}"
|
116
|
+
|
117
|
+
# TODO: Put this behind additional flag for extra control/sanity.
|
118
|
+
# Some executables are shell scripts and similar. For them we need to use the interpreter.
|
119
|
+
|
120
|
+
mime = Mime.new @executable_name, @executable_path
|
121
|
+
return unless mime.resolve_mime_type
|
122
|
+
|
123
|
+
# Then find out required libraries
|
124
|
+
|
125
|
+
library_mounts = []
|
126
|
+
|
127
|
+
library_object = ::Bwrap::Args::Library.new
|
128
|
+
libraries = library_object.libraries_needed_by mime.executable_path
|
129
|
+
|
130
|
+
# TODO: following is bad?
|
131
|
+
#library_object.needed_libraries(mime.executable_path).each do |library|
|
132
|
+
libraries.each do |library|
|
133
|
+
library_mounts << "--ro-bind" << library << library
|
134
|
+
end
|
135
|
+
|
136
|
+
@args.append library_mounts
|
137
|
+
end
|
138
|
+
|
139
|
+
# Some features, like {Bwrap::Config::Features::Nscd}, requires some binds
|
140
|
+
# in order to operate properly.
|
141
|
+
def binds_for_features
|
142
|
+
# NOTE: Still nothing here, as I think this is better for library binds than anything else.
|
143
|
+
# The nscd bind is better in another, more generic, place.
|
144
|
+
#
|
145
|
+
# Keeping this method because I think this really makes sense for structure, in future.
|
146
|
+
|
147
|
+
ruby_binds_for_features
|
148
|
+
end
|
149
|
+
|
150
|
+
# Used by {#libs_command_requires}.
|
151
|
+
private def resolve_executable_name command
|
152
|
+
if command.is_a? String
|
153
|
+
return command
|
154
|
+
end
|
155
|
+
|
156
|
+
# Array-like.
|
157
|
+
if command.respond_to? :at
|
158
|
+
return command.at(0)
|
159
|
+
end
|
160
|
+
|
161
|
+
raise "Can’t recognize type of given command. Type: #{command.class}"
|
162
|
+
end
|
163
|
+
|
164
|
+
# @warning Requires environment paths to be resolved beforehand.
|
165
|
+
#
|
166
|
+
# Used by {#libs_command_requires}.
|
167
|
+
private def resolve_executable_path executable_name, not_inside_root: nil
|
168
|
+
if @config&.command_inside_root.nil? or not_inside_root
|
169
|
+
return which executable_name
|
170
|
+
end
|
171
|
+
|
172
|
+
paths = @environment.env_paths.map do |path|
|
173
|
+
"#{@config.root}/#{path}"
|
174
|
+
end
|
175
|
+
env_path = paths.join ":"
|
176
|
+
|
177
|
+
which executable_name, env_path_var: env_path
|
178
|
+
end
|
179
|
+
|
180
|
+
private def ruby_binds_for_features
|
181
|
+
return unless @config.features.ruby.enabled?
|
182
|
+
|
183
|
+
binds = RubyBinds.new @args
|
184
|
+
binds.config = @config
|
185
|
+
binds.ruby_binds_for_features
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bwrap/execution"
|
4
|
+
require "bwrap/output"
|
5
|
+
|
6
|
+
class Bwrap::Args::Bind
|
7
|
+
# Inner class to clean up namespace for implementation specific reasons.
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
class Mime
|
11
|
+
include Bwrap::Execution
|
12
|
+
include Bwrap::Output
|
13
|
+
|
14
|
+
# Name given to {#initialize}.
|
15
|
+
attr_reader :executable_name
|
16
|
+
|
17
|
+
# Either path given to {#initialize} or one parsed from shebang.
|
18
|
+
attr_reader :executable_path
|
19
|
+
|
20
|
+
def initialize executable_name, executable_path
|
21
|
+
@executable_name = executable_name
|
22
|
+
@executable_path = executable_path
|
23
|
+
end
|
24
|
+
|
25
|
+
# Used by {Bwrap::Args::Bind::Library#libs_command_requires}.
|
26
|
+
#
|
27
|
+
# @return false if caller should also return
|
28
|
+
def resolve_mime_type
|
29
|
+
mime_type = execvalue %W{ file --brief --mime-type #{@executable_path} }
|
30
|
+
trace "Mime type of #{@executable_path} is #{mime_type}"
|
31
|
+
return true unless mime_type[0..6] == "text/x-"
|
32
|
+
|
33
|
+
shebang = File.open @executable_path, &:readline
|
34
|
+
if shebang[0..1] != "#!"
|
35
|
+
warn "Executable #{@executable_name} was recognized as #{mime_type} but does not have " \
|
36
|
+
"proper shebang line. Skipping automatic library mounts."
|
37
|
+
return false
|
38
|
+
end
|
39
|
+
|
40
|
+
resolve_real_executable shebang
|
41
|
+
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
45
|
+
private def resolve_real_executable shebang
|
46
|
+
command_line = shebang.delete_prefix("#!").strip
|
47
|
+
real_executable, args = command_line.split " ", 2
|
48
|
+
|
49
|
+
if [ "/usr/bin/env", "/bin/env" ].include? real_executable
|
50
|
+
# First argument is name of the executable, resolved from PATH.
|
51
|
+
executable_name = args.split(" ", 2).first
|
52
|
+
real_executable = which executable_name
|
53
|
+
end
|
54
|
+
|
55
|
+
@executable_path = real_executable
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/bwrap/args/bind.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require "bwrap/execution"
|
4
4
|
require "bwrap/output"
|
5
5
|
require_relative "args"
|
6
|
-
require_relative "library"
|
6
|
+
require_relative "bind/library"
|
7
7
|
|
8
8
|
# Bind arguments for bwrap.
|
9
9
|
class Bwrap::Args::Bind
|
@@ -18,52 +18,12 @@ class Bwrap::Args::Bind
|
|
18
18
|
# @see (see Bwrap::Args::Construct#command=)
|
19
19
|
attr_writer :command
|
20
20
|
|
21
|
-
# Instance of {Config}.
|
21
|
+
# Instance of {Bwrap::Config}.
|
22
22
|
attr_writer :config
|
23
23
|
|
24
24
|
# Instance of {Bwrap::Args::Environment}.
|
25
25
|
attr_writer :environment
|
26
26
|
|
27
|
-
# Inner class to clean up namespace for implementation specific reasons.
|
28
|
-
#
|
29
|
-
# @api internal
|
30
|
-
class Mime
|
31
|
-
include Bwrap::Execution
|
32
|
-
include Bwrap::Output
|
33
|
-
|
34
|
-
# Name given to {#initialize}.
|
35
|
-
attr_reader :executable_name
|
36
|
-
|
37
|
-
# Either path given to {#initialize} or one parsed from shebang.
|
38
|
-
attr_reader :executable_path
|
39
|
-
|
40
|
-
def initialize executable_name, executable_path
|
41
|
-
@executable_name = executable_name
|
42
|
-
@executable_path = executable_path
|
43
|
-
end
|
44
|
-
|
45
|
-
# Used by {Bwrap::Args::Bind#libs_command_requires}.
|
46
|
-
#
|
47
|
-
# @return false if caller should also return
|
48
|
-
def resolve_mime_type
|
49
|
-
mime_type = execvalue %W{ file --brief --mime-type #{@executable_path} }
|
50
|
-
return true unless mime_type[0..6] == "text/x-"
|
51
|
-
|
52
|
-
shebang = File.open @executable_path, &:readline
|
53
|
-
if shebang[0..1] != "#!"
|
54
|
-
warn "Executable #{@executable_name} was recognized as #{mime_type} but does not have " \
|
55
|
-
"proper shebang line. Skipping automatic library mounts."
|
56
|
-
return false
|
57
|
-
end
|
58
|
-
|
59
|
-
shebang = shebang.delete_prefix("#!").strip
|
60
|
-
real_executable, _args = shebang.split " ", 2
|
61
|
-
@executable_path = real_executable
|
62
|
-
|
63
|
-
true
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
27
|
# Arguments to bind /dev/dri from host to sandbox.
|
68
28
|
def bind_dev_dri
|
69
29
|
@args.append %w{ --dev-bind /dev/dri /dev/dri }
|
@@ -99,13 +59,13 @@ class Bwrap::Args::Bind
|
|
99
59
|
end
|
100
60
|
|
101
61
|
# Arguments to read-only bind whole system inside sandbox.
|
102
|
-
def
|
62
|
+
def handle_system_mounts
|
103
63
|
bindir_mounts = []
|
104
64
|
binaries_from = @config.binaries_from
|
105
65
|
binaries_from.each do |path|
|
106
66
|
bindir_mounts << "--ro-bind" << path << path
|
107
67
|
end
|
108
|
-
@environment
|
68
|
+
@environment.add_to_path binaries_from
|
109
69
|
|
110
70
|
@args.append bindir_mounts
|
111
71
|
|
@@ -117,10 +77,15 @@ class Bwrap::Args::Bind
|
|
117
77
|
|
118
78
|
libdir_mounts
|
119
79
|
|
80
|
+
library_bind = construct_library_bind
|
81
|
+
|
82
|
+
binds_for_features
|
83
|
+
library_bind.binds_for_features
|
84
|
+
library_bind.extra_executables_mounts
|
85
|
+
|
120
86
|
return unless @config.full_system_mounts
|
121
87
|
|
122
|
-
|
123
|
-
libs_command_requires
|
88
|
+
library_bind.libs_command_requires
|
124
89
|
end
|
125
90
|
|
126
91
|
# These are something user can specify to do custom --ro-bind binds.
|
@@ -132,10 +97,15 @@ class Bwrap::Args::Bind
|
|
132
97
|
binds << "--ro-bind" << source_path.to_s << destination_path.to_s
|
133
98
|
end
|
134
99
|
|
135
|
-
@args.append binds
|
100
|
+
@args.append binds unless binds.empty?
|
101
|
+
end
|
102
|
+
|
103
|
+
# Performs cleanup operations after execution.
|
104
|
+
def cleanup
|
105
|
+
Bwrap::Args::Library.clear_needed_libraries_cache
|
136
106
|
end
|
137
107
|
|
138
|
-
# Used by {#
|
108
|
+
# Used by {#handle_system_mounts}.
|
139
109
|
private def libdir_mounts
|
140
110
|
return unless @config.libdir_mounts
|
141
111
|
|
@@ -155,49 +125,17 @@ class Bwrap::Args::Bind
|
|
155
125
|
@args.append libdir_mounts
|
156
126
|
end
|
157
127
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
path = "/lib/ld-linux.so.2"
|
164
|
-
loader_mounts << "--ro-bind" << path << path if File.exist? path
|
128
|
+
private def construct_library_bind
|
129
|
+
library_bind = Bwrap::Args::Bind::Library.new @args
|
130
|
+
library_bind.command = @command
|
131
|
+
library_bind.config = @config
|
132
|
+
library_bind.environment = @environment
|
165
133
|
|
166
|
-
|
134
|
+
library_bind
|
167
135
|
end
|
168
136
|
|
169
|
-
#
|
170
|
-
|
171
|
-
|
172
|
-
#
|
173
|
-
# @warning scanelf does not play with spaces in names well. This method assumes that libraries
|
174
|
-
# have no spaces in names, though binaries can have.
|
175
|
-
#
|
176
|
-
# @todo Ensure scanelf is available (and throw proper error if it is not, telling to not use
|
177
|
-
# full_system_mounts option.)
|
178
|
-
private def libs_command_requires
|
179
|
-
executable_name = @command.is_a?(String) && @command || @command[0]
|
180
|
-
executable_path = which executable_name
|
181
|
-
|
182
|
-
# TODO: Put this behind additional flag for extra control/sanity.
|
183
|
-
# Some executables are shell scripts and similar. For them we need to use the interpreter.
|
184
|
-
|
185
|
-
mime = Mime.new executable_name, executable_path
|
186
|
-
return unless mime.resolve_mime_type
|
187
|
-
|
188
|
-
# Then find out required libraries
|
189
|
-
|
190
|
-
library_mounts = []
|
191
|
-
|
192
|
-
library_object = Bwrap::Args::Library.new
|
193
|
-
libraries = library_object.libraries_needed_by mime.executable_path
|
194
|
-
|
195
|
-
# TODO: following is bad?
|
196
|
-
#library_object.needed_libraries(mime.executable_path).each do |library|
|
197
|
-
libraries.each do |library|
|
198
|
-
library_mounts << "--ro-bind" << library << library
|
199
|
-
end
|
200
|
-
|
201
|
-
@args.append library_mounts
|
137
|
+
# Binds feature specific common directories.
|
138
|
+
private def binds_for_features
|
139
|
+
# Nya.
|
202
140
|
end
|
203
141
|
end
|
data/lib/bwrap/args/construct.rb
CHANGED
@@ -22,7 +22,7 @@ class Bwrap::Args::Construct
|
|
22
22
|
# setting {Config#full_system_mounts=} uses this to resolve some
|
23
23
|
# additional data.
|
24
24
|
#
|
25
|
-
# @param
|
25
|
+
# @param value [Array, String] Command with arguments
|
26
26
|
attr_writer :command
|
27
27
|
|
28
28
|
# Constructs arguments for bwrap execution.
|
@@ -35,7 +35,7 @@ class Bwrap::Args::Construct
|
|
35
35
|
machine_id = @machine_id.machine_id
|
36
36
|
@args.append machine_id if machine_id
|
37
37
|
resolv_conf
|
38
|
-
@bind.
|
38
|
+
@bind.handle_system_mounts
|
39
39
|
@features.feature_binds
|
40
40
|
@bind.custom_read_only_binds
|
41
41
|
create_user_dir
|
@@ -60,6 +60,7 @@ class Bwrap::Args::Construct
|
|
60
60
|
# Performs cleanup operations after execution.
|
61
61
|
def cleanup
|
62
62
|
@machine_id&.cleanup
|
63
|
+
@bind&.cleanup
|
63
64
|
end
|
64
65
|
|
65
66
|
# Used by {#construct_bwrap_args}.
|
@@ -1,24 +1,82 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "bwrap/execution"
|
3
4
|
require "bwrap/output"
|
4
5
|
require_relative "args"
|
5
6
|
|
6
7
|
# Environment variable calculation for bwrap.
|
7
8
|
class Bwrap::Args::Environment < Hash
|
9
|
+
include Bwrap::Execution
|
8
10
|
include Bwrap::Output
|
9
11
|
|
10
12
|
# Instance of {Config}.
|
11
13
|
attr_writer :config
|
12
14
|
|
13
|
-
|
15
|
+
def initialize
|
16
|
+
super
|
17
|
+
|
18
|
+
self["PATH"] ||= []
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns used environment variables wrapped as bwrap arguments.
|
14
22
|
def environment_variables
|
15
23
|
if debug?
|
16
24
|
debug "Passing following environment variables to bwrap:\n" \
|
17
25
|
"#{self}"
|
18
26
|
end
|
19
27
|
|
28
|
+
env_paths
|
29
|
+
|
20
30
|
map do |key, value|
|
31
|
+
if key == "PATH" and value.respond_to? :join
|
32
|
+
value = value.join ":"
|
33
|
+
end
|
34
|
+
|
21
35
|
[ "--setenv", key, value ]
|
22
36
|
end
|
23
37
|
end
|
38
|
+
|
39
|
+
# @return [Array] All environment paths added via {Config#add_env_path} and other parsing logic
|
40
|
+
def env_paths
|
41
|
+
if @config.env_paths.respond_to? :each
|
42
|
+
self["PATH"] |= @config.env_paths
|
43
|
+
end
|
44
|
+
|
45
|
+
features_env_paths
|
46
|
+
|
47
|
+
self["PATH"]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Adds given paths to PATH environment variable defined in the sandbox.
|
51
|
+
#
|
52
|
+
# @param elements [String, Array] Path(s) to be added added to PATH environment variable
|
53
|
+
def add_to_path elements
|
54
|
+
if elements.respond_to? :each
|
55
|
+
self["PATH"] += elements
|
56
|
+
else
|
57
|
+
# Expecting elements to be single path element as a string.
|
58
|
+
self["PATH"] << elements
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Feature specific environment path handling.
|
63
|
+
private def features_env_paths
|
64
|
+
ruby_env_paths
|
65
|
+
end
|
66
|
+
|
67
|
+
# Ruby feature specific environment path handling.
|
68
|
+
private def ruby_env_paths
|
69
|
+
return unless @config.features.ruby.enabled?
|
70
|
+
return unless @config.features.ruby.gem_env_paths?
|
71
|
+
|
72
|
+
unless command_available? "gem"
|
73
|
+
warn "gem is not installed in the system, so can’t add its bindirs to PATH."
|
74
|
+
return
|
75
|
+
end
|
76
|
+
|
77
|
+
gempath = execvalue %w{ gem environment gempath }
|
78
|
+
gempath.split(":").each do |path|
|
79
|
+
self["PATH"] << "#{path}/bin"
|
80
|
+
end
|
81
|
+
end
|
24
82
|
end
|
data/lib/bwrap/args/features.rb
CHANGED
@@ -10,8 +10,46 @@ require_relative "library"
|
|
10
10
|
class Bwrap::Args::Features < Hash
|
11
11
|
include Bwrap::Output
|
12
12
|
|
13
|
-
#
|
13
|
+
# Implementation for Bash feature set.
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
class BashBinds
|
17
|
+
# Mounts stuff like /bin/bash.
|
18
|
+
def bash_mounts
|
19
|
+
mounts = []
|
20
|
+
|
21
|
+
if File.file? "/bin/bash"
|
22
|
+
mounts << "--ro-bind" << "/bin/bash" << "/bin/bash"
|
23
|
+
end
|
24
|
+
if File.file? "/usr/bin/bash"
|
25
|
+
mounts << "--ro-bind" << "/usr/bin/bash" << "/usr/bin/bash"
|
26
|
+
end
|
27
|
+
|
28
|
+
mounts
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Implementation for nscd feature set.
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
class NscdBinds
|
36
|
+
# Custom binds needed by the feature.
|
37
|
+
def custom_binds
|
38
|
+
mounts = []
|
39
|
+
|
40
|
+
# TODO: Probably some path checking is needed here. Or somewhere.
|
41
|
+
# TODO: Since on many systems /var/run is symlinked to /run, that probably should be handled.
|
42
|
+
mounts << "--ro-bind" << "/var/run/nscd" << "/var/run/nscd"
|
43
|
+
|
44
|
+
mounts
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Implementation for Ruby feature set.
|
49
|
+
#
|
50
|
+
# @api private
|
14
51
|
class RubyBinds
|
52
|
+
# Returns mounts needed by Ruby feature set.
|
15
53
|
attr_reader :mounts
|
16
54
|
|
17
55
|
# Bind system paths so scripts works inside sandbox.
|
@@ -40,19 +78,43 @@ class Bwrap::Args::Features < Hash
|
|
40
78
|
library_mounts << "--ro-bind" << requisite_library << requisite_library
|
41
79
|
end
|
42
80
|
end
|
81
|
+
|
82
|
+
library_mounts
|
43
83
|
end
|
44
84
|
end
|
45
85
|
|
46
|
-
#
|
86
|
+
# `Array` of parameters passed to bwrap.
|
47
87
|
attr_writer :args
|
48
88
|
|
49
89
|
# Instance of {Config}.
|
50
90
|
attr_writer :config
|
51
91
|
|
92
|
+
# Resolves binds required by different features.
|
93
|
+
#
|
94
|
+
# Currently implemented feature sets:
|
95
|
+
# - ruby
|
52
96
|
def feature_binds
|
97
|
+
bash_binds
|
98
|
+
nscd_binds
|
53
99
|
ruby_binds
|
54
100
|
end
|
55
101
|
|
102
|
+
private def bash_binds
|
103
|
+
return unless @config.features.bash.enabled?
|
104
|
+
|
105
|
+
binds = BashBinds.new
|
106
|
+
|
107
|
+
@args.append binds.bash_mounts
|
108
|
+
end
|
109
|
+
|
110
|
+
private def nscd_binds
|
111
|
+
return unless @config.features.nscd.enabled?
|
112
|
+
|
113
|
+
binds = NscdBinds.new
|
114
|
+
|
115
|
+
@args.append binds.custom_binds
|
116
|
+
end
|
117
|
+
|
56
118
|
# @note This does not allow development headers needed for compilation for now.
|
57
119
|
# I’ll look at it after I have an use for it.
|
58
120
|
private def ruby_binds
|
@@ -61,6 +123,6 @@ class Bwrap::Args::Features < Hash
|
|
61
123
|
binds = RubyBinds.new
|
62
124
|
|
63
125
|
@args.append binds.sitedir_mounts
|
64
|
-
@args.append binds.stdlib_mounts
|
126
|
+
@args.append binds.stdlib_mounts(@config.features.ruby.stdlib)
|
65
127
|
end
|
66
128
|
end
|