bwrap 1.1.1 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base"
4
+
5
+ # Used via {Bwrap::Resolvers::Library}.
6
+ #
7
+ # @api private
8
+ class Bwrap::Resolvers::Library::Musl < Bwrap::Resolvers::Library::Base
9
+ # @param binary_paths [String, Array] one or more paths to be resolved
10
+ def needed_libraries binary_paths
11
+ trace "Finding musl libraries #{binary_paths} requires"
12
+ @needed_libraries = []
13
+
14
+ binary_paths = convert_binary_paths binary_paths
15
+
16
+ # Check if the exe is already resolved.
17
+ binary_paths.delete_if do |binary_path|
18
+ Bwrap::Resolvers::Library.needed_libraries_cache.include? binary_path
19
+ end
20
+
21
+ return [] if binary_paths.empty?
22
+
23
+ binary_paths.each do |binary_path|
24
+ output = execvalue %W{ ldd #{binary_path} }
25
+ lines = output.split "\n"
26
+ _interpreter_line = lines.shift
27
+
28
+ lines.each do |line|
29
+ parse_ldd_line line
30
+ end
31
+ end
32
+
33
+ @needed_libraries
34
+ end
35
+
36
+ # Used by {#musl_needed_libraries}.
37
+ private def parse_ldd_line line
38
+ line = line.strip
39
+ _library_name, library_data = line.split " => "
40
+
41
+ matches = library_data.match(/(.*) \(0x[0-9a-f]+\)/)
42
+ library_path = matches[1]
43
+
44
+ unless @needed_libraries.include? library_path
45
+ @needed_libraries << library_path
46
+ end
47
+
48
+ # Also check if requisite libraries needs some libraries.
49
+ inner = Bwrap::Resolvers::Library.new
50
+ @needed_libraries |= inner.musl_needed_libraries library_path
51
+
52
+ Bwrap::Resolvers::Library.needed_libraries_cache << library_path
53
+ end
54
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "resolvers"
4
+
5
+ # Class to clean up namespace for implementation specific reasons.
6
+ #
7
+ # @api private
8
+ class Bwrap::Resolvers::Library
9
+ # Declared here only for convenience.
10
+ end
11
+
12
+ require_relative "library/library"
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bwrap/execution"
4
+ require "bwrap/output"
5
+ require_relative "resolvers"
6
+
7
+ # Finds out mime type of given executable.
8
+ #
9
+ # @api private
10
+ class Bwrap::Resolvers::Mime
11
+ include Bwrap::Execution
12
+ include Bwrap::Execution::Path
13
+ include Bwrap::Output
14
+
15
+ # Name given to {#initialize}.
16
+ attr_reader :executable_name
17
+
18
+ # Either path given to {#initialize} or one parsed from shebang.
19
+ attr_reader :executable_path
20
+
21
+ # @return [String|nil] Resolved mime type of the executable
22
+ attr_reader :mime_type
23
+
24
+ def initialize executable_name, executable_path
25
+ @executable_name = executable_name
26
+ @executable_path = executable_path
27
+ end
28
+
29
+ # Checks if target executable is a script, in which case executable
30
+ # is parsed from a shebang line, if found.
31
+ def resolve_mime_type
32
+ @mime_type = execvalue %W{ file --brief --mime-type #{@executable_path} }
33
+ trace "Mime type of #{@executable_path} is #{@mime_type}"
34
+ end
35
+
36
+ # Checks if the executable is run using another executable,
37
+ # using a shebang.
38
+ #
39
+ # For example, if the executable is a bash script, returns `true`.
40
+ def interpreter?
41
+ return false unless @mime_type[0..6] == "text/x-"
42
+
43
+ @shebang_line = File.open @executable_path, &:readline
44
+ if @shebang_line[0..1] != "#!"
45
+ return false
46
+ end
47
+
48
+ true
49
+ end
50
+
51
+ # Parses shebang line to find out path to actual executable
52
+ # used to run the script.
53
+ #
54
+ # TODO: Handle this is better way.
55
+ def resolve_real_executable
56
+ # Following sets @shebang_line.
57
+ interpreter? if @shebang_line.nil?
58
+
59
+ shebang = @shebang_line
60
+ #trace "Figuring out correct executable from shebang #{shebang}"
61
+
62
+ command_line = shebang.delete_prefix("#!").strip
63
+ real_executable, args = command_line.split " ", 2
64
+
65
+ if [ "/usr/bin/env", "/bin/env" ].include? real_executable
66
+ # First argument is name of the executable, resolved from PATH.
67
+ executable_name = args.split(" ", 2).first
68
+ real_executable = which executable_name
69
+ end
70
+
71
+ debug "Parsed #{real_executable} from the script’s shebang. Using as executable."
72
+
73
+ real_executable
74
+ end
75
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bwrap/bwrap_module"
4
+
5
+ # Classes that allows resolution of executable dependencies, for example.
6
+ module Bwrap::Resolvers
7
+ end
data/lib/bwrap/version.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Bwrap
4
4
  # Current version of bwrap.
5
- VERSION = "1.1.1"
5
+ VERSION = "1.3.1"
6
6
  end
7
7
 
8
8
  require "deep-cover" if ENV["DEEP_COVER"]
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bwrap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samu Voutilainen
@@ -10,8 +10,8 @@ bindir: bin
10
10
  cert_chain:
11
11
  - |
12
12
  -----BEGIN CERTIFICATE-----
13
- MIIEJDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDDBNid3Jh
14
- cC9EQz1zbWFyL0RDPWZpMB4XDTIxMTAyMDA0NTkwOVoXDTIyMTAyMDA0NTkwOVow
13
+ MIID8DCCAligAwIBAgIBAjANBgkqhkiG9w0BAQsFADAeMRwwGgYDVQQDDBNid3Jh
14
+ cC9EQz1zbWFyL0RDPWZpMB4XDTIzMDEwNjA2NTUyNFoXDTI0MDEwNjA2NTUyNFow
15
15
  HjEcMBoGA1UEAwwTYndyYXAvREM9c21hci9EQz1maTCCAaIwDQYJKoZIhvcNAQEB
16
16
  BQADggGPADCCAYoCggGBAKUQ5wFdLLIejwiCNeGMlbApquoC0jT59H+d6zOLWxYd
17
17
  RRdum9G1lxFFFolEsFj5RSplg/SlhAhYRMUjDHiSk/usxVcOt28h4sdiFTbi1zKA
@@ -21,20 +21,19 @@ cert_chain:
21
21
  NqpsI0mQejnq+QdiNz9gAWObO+UhrOv5S7E0NYQTaf1e3G56kCmIG9p0pFXjWNPx
22
22
  DhL6YDoizVSQKTllYWbDhBx0+D+sevtmKAy0vHDAY33teAQYOxgeE/iXqvvROPU7
23
23
  HNOAqNazQHwPsTepLT9Dc/5bVbazL1MNNiWh5ZYjmJnlGSttHhM/xsZZkckJ20oh
24
- 0iJSyUprpR2epHP8832n6wIDAQABo20wazAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
25
- sDAdBgNVHQ4EFgQUywyVCkA/Pr5zdaaMvAVlHKSXeJkwGAYDVR0RBBEwD4ENYndy
26
- YXBAc21hci5maTAYBgNVHRIEETAPgQ1id3JhcEBzbWFyLmZpMA0GCSqGSIb3DQEB
27
- CwUAA4IBgQB6mMDP9dY/aJZhNgZMx2d18nPLuKzTUieWJv13uPDileUbN0/nr+w4
28
- dFDOTa/yjcp0mWQLF1mP/f3T8cwExlZzffftjX7dDZQJNWx3OCUHyS3GRowAE61F
29
- dIWRUjd3RBfZEVrx/xY1OVp5T+N8Qn6g84Xp2OxO8GR95YlFX4WKun8f6kDEjfVi
30
- m+Kso0RI4aJ93vOlm56mteupRLPyrA7dIcXG1qsglckNk3NnNvtAPSC7ncI43N3x
31
- NZXFxgnAa3HZcJPhaPWpViVvrSdIYAa8ZLhvfIaDml3RE320+MenIWIqnpuwiFCg
32
- jpHgtXCEQSwZTEkKj7NoUBkDjVOKnF6CB9nR4l564+BRWvtN0RJBKMmBIx3LP9vm
33
- BwxPnxDROuNLx3wckCTGRH61p/K84L6Y2VEC6X+A2ztKVIjv+qRgH6NdhGFOf8US
34
- X4ioQwEn1/9tHs19VO1CLF58451HgEo1BXd7eWLmV1V5cqw0YWok1ly4L/Su/Phf
35
- MRxVMHiVAqY=
24
+ 0iJSyUprpR2epHP8832n6wIDAQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE
25
+ sDAdBgNVHQ4EFgQUywyVCkA/Pr5zdaaMvAVlHKSXeJkwDQYJKoZIhvcNAQELBQAD
26
+ ggGBAGmSe4zkcmNd3JfmTA9CDpBu3j6qiPnbk2x8vTjDQAyAGRjX8Depzz39jUbF
27
+ cmmL/J5XqqkZaYy7X+w2nWVYk8BwmAP3ft6L6qO0rmZhOtfsyTzf0fI1zY20Y98W
28
+ uoDoS2cL6fIJ8Gv6B4tXCSZO1cQOHMAhzAeRGbfn0InbDtalfVbYFmnmo9PqJz4C
29
+ kRUFHNCTRt+YAneAZ2gAU4r89EuNheyyEmPonWHjCwPIGKS/rsChFWIU22wrZkGd
30
+ aWT3as+jC2gDiQTw82JalFWsqK9p9UxsRt1lkV4mb5NSDcKl7ApI1TAW2EANeLOx
31
+ PWJbiDgQIrErC5lDu25gzWF+g5sYc7uaMcKxS8BqAggMWuW/lUcNX8e+4WdDAPgO
32
+ tDIK8ZQo4kVJE9EQTA4LsP4TMNDn18vBr0aIY92p+uq31rocusojfAszU50DSw3M
33
+ 7a31nUjVeQjpooaUQi6ECFr+Neidh3jhzreVfXqjxMkPOYLlCAmd9E1izCTRIgLS
34
+ cAzqsw==
36
35
  -----END CERTIFICATE-----
37
- date: 2022-06-07 00:00:00.000000000 Z
36
+ date: 2023-01-06 00:00:00.000000000 Z
38
37
  dependencies:
39
38
  - !ruby/object:Gem::Dependency
40
39
  name: bundler
@@ -148,29 +147,33 @@ files:
148
147
  - lib/bwrap.rb
149
148
  - lib/bwrap/args/args.rb
150
149
  - lib/bwrap/args/bind.rb
150
+ - lib/bwrap/args/bind/device.rb
151
151
  - lib/bwrap/args/bind/library.rb
152
152
  - lib/bwrap/args/bind/library/ruby_binds.rb
153
- - lib/bwrap/args/bind/mime.rb
154
153
  - lib/bwrap/args/construct.rb
155
154
  - lib/bwrap/args/environment.rb
156
155
  - lib/bwrap/args/features.rb
157
156
  - lib/bwrap/args/features/binds_base.rb
158
157
  - lib/bwrap/args/features/ruby_binds.rb
159
- - lib/bwrap/args/library.rb
160
158
  - lib/bwrap/args/machine_id.rb
161
159
  - lib/bwrap/args/mount.rb
160
+ - lib/bwrap/args/namespace.rb
162
161
  - lib/bwrap/args/network.rb
162
+ - lib/bwrap/args/user.rb
163
163
  - lib/bwrap/bwrap.rb
164
164
  - lib/bwrap/bwrap_module.rb
165
165
  - lib/bwrap/config.rb
166
166
  - lib/bwrap/config/features.rb
167
167
  - lib/bwrap/config/features/base.rb
168
168
  - lib/bwrap/config/features/ruby.rb
169
+ - lib/bwrap/exceptions.rb
169
170
  - lib/bwrap/execution.rb
170
171
  - lib/bwrap/execution/exceptions.rb
172
+ - lib/bwrap/execution/exec.rb
171
173
  - lib/bwrap/execution/execute.rb
172
174
  - lib/bwrap/execution/execution.rb
173
175
  - lib/bwrap/execution/labels.rb
176
+ - lib/bwrap/execution/logging.rb
174
177
  - lib/bwrap/execution/path.rb
175
178
  - lib/bwrap/execution/popen2e.rb
176
179
  - lib/bwrap/output.rb
@@ -178,6 +181,14 @@ files:
178
181
  - lib/bwrap/output/levels.rb
179
182
  - lib/bwrap/output/log.rb
180
183
  - lib/bwrap/output/output_impl.rb
184
+ - lib/bwrap/resolvers/executable.rb
185
+ - lib/bwrap/resolvers/library.rb
186
+ - lib/bwrap/resolvers/library/base.rb
187
+ - lib/bwrap/resolvers/library/library.rb
188
+ - lib/bwrap/resolvers/library/llvm_readelf.rb
189
+ - lib/bwrap/resolvers/library/musl.rb
190
+ - lib/bwrap/resolvers/mime.rb
191
+ - lib/bwrap/resolvers/resolvers.rb
181
192
  - lib/bwrap/version.rb
182
193
  homepage: https://git.sr.ht/~smar/ruby-bwrap
183
194
  licenses:
metadata.gz.sig CHANGED
Binary file
@@ -1,65 +0,0 @@
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
- # Checks if target executable is a script, in which case executable
26
- # is parsed from a shebang line, if found.
27
- #
28
- # @return false if caller should also return
29
- def resolve_mime_type
30
- mime_type = execvalue %W{ file --brief --mime-type #{@executable_path} }
31
- debug "Mime type of #{@executable_path} is #{mime_type}"
32
- return true unless mime_type[0..6] == "text/x-"
33
-
34
- shebang = File.open @executable_path, &:readline
35
- if shebang[0..1] != "#!"
36
- warn "Executable #{@executable_name} was recognized as #{mime_type} but does not have " \
37
- "proper shebang line. Skipping automatic library mounts."
38
- return false
39
- end
40
-
41
- resolve_real_executable shebang
42
-
43
- true
44
- end
45
-
46
- # Parses shebang line to find out path to actual executable
47
- # used to run the script.
48
- private def resolve_real_executable shebang
49
- #trace "Figuring out correct executable from shebang #{shebang}"
50
-
51
- command_line = shebang.delete_prefix("#!").strip
52
- real_executable, args = command_line.split " ", 2
53
-
54
- if [ "/usr/bin/env", "/bin/env" ].include? real_executable
55
- # First argument is name of the executable, resolved from PATH.
56
- executable_name = args.split(" ", 2).first
57
- real_executable = which executable_name
58
- end
59
-
60
- debug "Parsed #{real_executable} from the script’s shebang. Using as executable."
61
-
62
- @executable_path = real_executable
63
- end
64
- end
65
- end
@@ -1,135 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bwrap/execution"
4
- require "bwrap/output"
5
- require_relative "args"
6
-
7
- # Class to clean up namespace for implementation specific reasons.
8
- #
9
- # @api private
10
- class Bwrap::Args::Library
11
- include Bwrap::Execution
12
- include Bwrap::Output
13
-
14
- # NOTE: This caching can be made more efficient, but need to look at it later, what to do about it.
15
- @@needed_libraries_cache ||= []
16
-
17
- # Empties {@@needed_libraries_cache}.
18
- def self.clear_needed_libraries_cache
19
- @@needed_libraries_cache.clear
20
- end
21
-
22
- # Otherwise similar to {#needed_libraries}, but checks used libc to handle musl executables.
23
- #
24
- # @param executable [String] Path to the executable to find dependencies for
25
- def libraries_needed_by executable
26
- # %i == interpreter, the library used to load the executable by kernel.
27
- # %F == Path to given file.
28
- output_format = "%i::SEPARATOR::%F"
29
- scanelf_command = %W{ scanelf --nobanner --quiet --format #{output_format} }
30
- scanelf_command << executable
31
-
32
- data = execvalue scanelf_command
33
- data = data.strip
34
- interpreter, _executable_path = data.split "::SEPARATOR::"
35
- interpreter = Pathname.new interpreter
36
-
37
- if interpreter.basename.to_s[0..6] == "ld-musl"
38
- musl_needed_libraries executable
39
- else
40
- # For glibc, scanelf can return full paths for us most of time.
41
- needed_libraries executable
42
- end
43
- end
44
-
45
- # @param binary_paths [String, Array] one or more paths to be resolved
46
- #
47
- # @todo Maybe caching should be done here too?
48
- def musl_needed_libraries binary_paths
49
- trace "Finding musl libraries #{binary_paths} requires"
50
- @needed_libraries = []
51
-
52
- if binary_paths.is_a? String
53
- binary_paths = [ binary_paths ]
54
- end
55
-
56
- binary_paths.each do |binary_path|
57
- output = execvalue %W{ ldd #{binary_path} }
58
- lines = output.split "\n"
59
- _interpreter_line = lines.shift
60
-
61
- lines.each do |line|
62
- parse_ldd_line line
63
- end
64
- end
65
-
66
- @needed_libraries
67
- end
68
-
69
- # @param binary_paths [String, Array] one or more paths to be resolved
70
- def needed_libraries binary_paths
71
- trace "Finding libraries #{binary_paths} requires"
72
- @needed_libraries = []
73
-
74
- # %i == interpreter, the library used to load the executable by kernel.
75
- output_format = "%F::SEPARATOR::%n"
76
- scanelf_command = %W{ scanelf --nobanner --quiet --format #{output_format} --ldcache --needed }
77
-
78
- if binary_paths.is_a? String
79
- binary_paths = [ binary_paths ]
80
- end
81
-
82
- # Check if the exe is already resolved.
83
- binary_paths.delete_if do |binary_path|
84
- @@needed_libraries_cache.include? binary_path
85
- end
86
-
87
- return [] if binary_paths.empty?
88
-
89
- data = execvalue(scanelf_command + binary_paths)
90
- trace "scanelf found following libraries: #{data}"
91
-
92
- lines = data.split "\n"
93
- lines.each do |line|
94
- parse_scanelf_line line
95
- end
96
-
97
- @needed_libraries
98
- end
99
-
100
- # Used by {#needed_libraries}.
101
- private def parse_scanelf_line line
102
- binary_path, libraries_line = line.split "::SEPARATOR::"
103
- libraries = libraries_line.split ","
104
-
105
- (@needed_libraries & libraries).each do |library|
106
- debug "Binding #{library} as dependency of #{binary_path}"
107
- end
108
-
109
- @needed_libraries |= libraries
110
-
111
- # Also check if requisite libraries needs some libraries.
112
- inner = Bwrap::Args::Library.new
113
- @needed_libraries |= inner.needed_libraries libraries
114
-
115
- @@needed_libraries_cache |= libraries
116
- end
117
-
118
- # Used by {#musl_needed_libraries}.
119
- private def parse_ldd_line line
120
- line = line.strip
121
- _library_name, library_data = line.split " => "
122
-
123
- matches = library_data.match(/(.*) \(0x[0-9a-f]+\)/)
124
- library_path = matches[1]
125
-
126
- unless @needed_libraries.include? library_path
127
- @needed_libraries << library_path
128
- end
129
-
130
- # Also check if requisite libraries needs some libraries.
131
- inner = Bwrap::Args::Library.new
132
- @needed_libraries |= inner.musl_needed_libraries library_path
133
- end
134
- end
135
- # class Library ended