pledge 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +4 -0
- data/Rakefile +10 -3
- data/ext/pledge/extconf.rb +1 -1
- data/ext/pledge/pledge.c +4 -0
- data/lib/unveil.rb +9 -2
- data/spec/pledge_spec.rb +3 -86
- metadata +36 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f794b6f397a93e9eaabdfff4928f49537fb0a45b55c042c7dc27c46d27918f5a
|
4
|
+
data.tar.gz: a0291c2d672594938292c7a6a83cc111d3c54679ea412c679e28087b8a870a89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9242a1de3c01334a60cb13ab98410dbe533e089228cf1a7a7cfdbb55a6d1ca7614aacbb306974ff85db1165b02a68e292ee9704038e41e9fab5100cccc7b68dc
|
7
|
+
data.tar.gz: e51bf3d1b375e5eba599052423fce0438cb21b3810b8dd38d6a26d7543bba2db8e8547edd0b53bbab99c999dfdead8b6f68e88620cfd9368a0c67bfcdf1c3d37
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
=== 1.3.0 (2022-12-19)
|
2
|
+
|
3
|
+
* Allow installation on platforms not supporting pledge, raising NotImplementedError when calling pledge/unveil methods in that case (jcs) (#3)
|
4
|
+
|
1
5
|
=== 1.2.0 (2019-07-07)
|
2
6
|
|
3
7
|
* Add unveil library and Pledge.unveil for access to unveil(2) to control file system access (jeremyevans)
|
data/Rakefile
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require "rake"
|
2
1
|
require "rake/clean"
|
3
2
|
|
4
|
-
CLEAN.include %w'
|
3
|
+
CLEAN.include %w'lib/*.so tmp coverage'
|
5
4
|
|
6
5
|
desc "Build the gem"
|
7
6
|
task :package do
|
@@ -11,12 +10,20 @@ end
|
|
11
10
|
desc "Run specs"
|
12
11
|
task :spec => :compile do
|
13
12
|
ruby = ENV['RUBY'] ||= FileUtils::RUBY
|
14
|
-
sh %{#{ruby} spec/pledge_spec.rb}
|
13
|
+
sh %{#{ruby} #{"-w" if RUBY_VERSION >= '3'} spec/pledge_spec.rb}
|
15
14
|
end
|
16
15
|
|
17
16
|
desc "Run specs"
|
18
17
|
task :default => :spec
|
19
18
|
|
19
|
+
desc "Run specs with coverage"
|
20
|
+
task :spec_cov => [:compile] do
|
21
|
+
ruby = ENV['RUBY'] ||= FileUtils::RUBY
|
22
|
+
ENV['COVERAGE'] = '1'
|
23
|
+
FileUtils.rm_rf('coverage')
|
24
|
+
sh %{#{ruby} spec/unveil_spec.rb}
|
25
|
+
end
|
26
|
+
|
20
27
|
begin
|
21
28
|
require 'rake/extensiontask'
|
22
29
|
Rake::ExtensionTask.new('pledge')
|
data/ext/pledge/extconf.rb
CHANGED
data/ext/pledge/pledge.c
CHANGED
@@ -13,6 +13,7 @@ static VALUE rb_pledge(int argc, VALUE* argv, VALUE pledge_class) {
|
|
13
13
|
const char * prom = NULL;
|
14
14
|
const char * execprom = NULL;
|
15
15
|
|
16
|
+
#ifdef HAVE_PLEDGE
|
16
17
|
rb_scan_args(argc, argv, "11", &promises, &execpromises);
|
17
18
|
|
18
19
|
if (!NIL_P(promises)) {
|
@@ -41,6 +42,9 @@ static VALUE rb_pledge(int argc, VALUE* argv, VALUE pledge_class) {
|
|
41
42
|
rb_raise(ePledgeError, "pledge error");
|
42
43
|
}
|
43
44
|
}
|
45
|
+
#else
|
46
|
+
rb_raise(rb_eNotImpError, "pledge not supported");
|
47
|
+
#endif
|
44
48
|
|
45
49
|
return Qnil;
|
46
50
|
}
|
data/lib/unveil.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
|
-
|
4
|
-
raise LoadError, "unveil not supported" unless Pledge.respond_to?(:_unveil, true)
|
3
|
+
require_relative 'pledge'
|
5
4
|
|
6
5
|
module Pledge
|
7
6
|
# Limit access to the file system using unveil(2). +paths+ should be a hash
|
@@ -23,6 +22,10 @@ module Pledge
|
|
23
22
|
# which denies all access to the file system if +unveil_without_lock+
|
24
23
|
# was not called previously.
|
25
24
|
def unveil(paths)
|
25
|
+
# :nocov:
|
26
|
+
raise NotImplementedError, "unveil not supported" unless Pledge.respond_to?(:_unveil, true)
|
27
|
+
# :nocov:
|
28
|
+
|
26
29
|
if paths.empty?
|
27
30
|
paths = {'/'=>''}
|
28
31
|
end
|
@@ -33,6 +36,10 @@ module Pledge
|
|
33
36
|
|
34
37
|
# Same as unveil, but allows for future calls to unveil or unveil_without_lock.
|
35
38
|
def unveil_without_lock(paths)
|
39
|
+
# :nocov:
|
40
|
+
raise NotImplementedError, "unveil not supported" unless Pledge.respond_to?(:_unveil, true)
|
41
|
+
# :nocov:
|
42
|
+
|
36
43
|
paths = Hash[paths]
|
37
44
|
|
38
45
|
paths.to_a.each do |path, perm|
|
data/spec/pledge_spec.rb
CHANGED
@@ -1,11 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
ENV['MT_NO_PLUGINS'] = '1' # Work around stupid autoloading of plugins
|
5
|
-
gem 'minitest'
|
6
|
-
require 'minitest/autorun'
|
7
|
-
|
8
|
-
RUBY = ENV['RUBY'] || 'ruby'
|
1
|
+
require_relative 'unveil_spec'
|
9
2
|
|
10
3
|
describe "Pledge.pledge" do
|
11
4
|
def execpledged(promises, execpromises, code)
|
@@ -73,8 +66,8 @@ describe "Pledge.pledge" do
|
|
73
66
|
|
74
67
|
it "should allow dns lookups if dns is used" do
|
75
68
|
with_lib('socket') do
|
76
|
-
unpledged("
|
77
|
-
pledged("
|
69
|
+
unpledged("Addrinfo.getaddrinfo('google.com', nil)")
|
70
|
+
pledged("Addrinfo.getaddrinfo('google.com', nil)", "dns")
|
78
71
|
end
|
79
72
|
end
|
80
73
|
|
@@ -136,79 +129,3 @@ describe "Pledge.pledge" do
|
|
136
129
|
execpledged(nil, "stdio", "$stderr.reopen('/dev/null', 'w'); exit(`cat MIT-LICENSE` == File.read('MIT-LICENSE'))").must_equal false
|
137
130
|
end
|
138
131
|
end
|
139
|
-
|
140
|
-
describe "Pledge.unveil" do
|
141
|
-
def unveiled(unveils, code)
|
142
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', "Pledge.unveil(#{unveils.inspect}); #{code}")
|
143
|
-
end
|
144
|
-
|
145
|
-
test_file = "spec/#{$$}_test.rb"
|
146
|
-
|
147
|
-
after do
|
148
|
-
File.delete(test_file) if File.file?(test_file)
|
149
|
-
end
|
150
|
-
|
151
|
-
it "should handle unveiling paths" do
|
152
|
-
unveiled({}, "exit(Dir['*'].empty?)").must_equal true
|
153
|
-
unveiled({'.'=>'r'}, "exit(!Dir['*'].empty?)").must_equal true
|
154
|
-
|
155
|
-
test_read = "exit(((File.read('MIT-LICENSE'); true) rescue false))"
|
156
|
-
unveiled({'.'=>'w'}, test_read).must_equal false
|
157
|
-
unveiled({'.'=>'r'}, test_read).must_equal true
|
158
|
-
unveiled({'.'=>'r'}, "exit(((File.open('MIT-LICENSE', 'w'){}; true) rescue false))").must_equal false
|
159
|
-
|
160
|
-
%w'rwxc rwx rwc rxc rx rw rc'.each do |perm|
|
161
|
-
unveiled({'.'=>perm}, test_read).must_equal true
|
162
|
-
end
|
163
|
-
|
164
|
-
%w'wxc wx wc xc x w c'.each do |perm|
|
165
|
-
unveiled({'.'=>perm}, test_read).must_equal false
|
166
|
-
end
|
167
|
-
|
168
|
-
unveiled({'MIT-LICENSE'=>'r'}, test_read).must_equal true
|
169
|
-
unveiled({'Rakefile'=>'r'}, test_read).must_equal false
|
170
|
-
unveiled({'.'=>'r', 'MIT-LICENSE'=>''}, test_read).must_equal false
|
171
|
-
unveiled({}, "Pledge.unveil{} rescue exit(1)").must_equal false
|
172
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', "Pledge.unveil_without_lock({'.'=>'r'}); Pledge.unveil({}); #{test_read}").must_equal true
|
173
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', "Pledge.unveil('foo/bar'=>'r') rescue exit(1)").must_equal false
|
174
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', "Pledge.send(:_unveil, '.', 'f') rescue exit(1)").must_equal false
|
175
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', "Pledge.unveil({1=>'s'}) rescue exit(1)").must_equal false
|
176
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', "Pledge.unveil({'s'=>1}) rescue exit(1)").must_equal false
|
177
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', "Pledge.send(:_unveil, 1, 'r') rescue exit(1)").must_equal false
|
178
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', "Pledge.send(:_unveil, '.', 1) rescue exit(1)").must_equal false
|
179
|
-
end
|
180
|
-
|
181
|
-
it "should handle require after unveil with read access after removing from $LOADED_FEATURES" do
|
182
|
-
[File.join('.', test_file), File.join(Dir.pwd, test_file)].each do |f|
|
183
|
-
f = f.inspect
|
184
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', <<-END).must_equal true
|
185
|
-
File.open(#{f}, 'w'){|f| f.write '1'}
|
186
|
-
require #{f}
|
187
|
-
Pledge.unveil('spec'=>'r')
|
188
|
-
$LOADED_FEATURES.delete #{f}
|
189
|
-
require #{f}
|
190
|
-
END
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
it "should handle :gem value to unveil gems" do
|
195
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', "$stderr.reopen('/dev/null', 'w'); require 'rubygems'; gem 'minitest'; require 'minitest'; Pledge.unveil({}); require 'minitest/benchmark' rescue exit(1)").must_equal false
|
196
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', "require 'rubygems'; gem 'minitest'; require 'minitest'; Pledge.unveil('minitest'=>:gem); require 'minitest/benchmark' rescue (p $!; puts $!.backtrace; exit(1))").must_equal true
|
197
|
-
|
198
|
-
system(RUBY, '-I', 'lib', '-r', 'unveil', '-e', "Pledge.unveil('gadzooks!!!'=>:gem) rescue exit(1)").must_equal false
|
199
|
-
end
|
200
|
-
|
201
|
-
it "should need create and write access for writing new files, and create access for removing files" do
|
202
|
-
unveiled({'.'=>'w'}, "File.open(#{test_file.inspect}, 'w'){|f| f.write '1'} rescue exit(1)").must_equal false
|
203
|
-
File.file?(test_file).must_equal false
|
204
|
-
unveiled({'.'=>'c'}, "File.open(#{test_file.inspect}, 'w'){|f| f.write '1'} rescue exit(1)").must_equal false
|
205
|
-
File.file?(test_file).must_equal false
|
206
|
-
unveiled({'.'=>'cw'}, "File.open(#{test_file.inspect}, 'w'){|f| f.write '1'}").must_equal true
|
207
|
-
File.read(test_file).must_equal '1'
|
208
|
-
|
209
|
-
unveiled({'.'=>'w'}, "File.delete(#{test_file.inspect}) rescue exit(1)").must_equal false
|
210
|
-
File.read(test_file).must_equal '1'
|
211
|
-
unveiled({'.'=>'c'}, "File.delete(#{test_file.inspect})").must_equal true
|
212
|
-
File.file?(test_file).must_equal false
|
213
|
-
end
|
214
|
-
end if Pledge.respond_to?(:_unveil, true)
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pledge
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2022-12-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: minitest-global_expectations
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake-compiler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
description: |
|
14
42
|
pledge exposes OpenBSD's pledge(2) and unveil(2) system calls to Ruby, allowing
|
15
43
|
a program to restrict the types of operations the program can do, and the file
|
@@ -38,7 +66,7 @@ homepage: https://github.com/jeremyevans/ruby-pledge
|
|
38
66
|
licenses:
|
39
67
|
- MIT
|
40
68
|
metadata: {}
|
41
|
-
post_install_message:
|
69
|
+
post_install_message:
|
42
70
|
rdoc_options:
|
43
71
|
- "--quiet"
|
44
72
|
- "--line-numbers"
|
@@ -53,15 +81,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
53
81
|
requirements:
|
54
82
|
- - ">="
|
55
83
|
- !ruby/object:Gem::Version
|
56
|
-
version: 1.
|
84
|
+
version: 1.9.2
|
57
85
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
86
|
requirements:
|
59
87
|
- - ">="
|
60
88
|
- !ruby/object:Gem::Version
|
61
89
|
version: '0'
|
62
90
|
requirements: []
|
63
|
-
rubygems_version: 3.
|
64
|
-
signing_key:
|
91
|
+
rubygems_version: 3.3.26
|
92
|
+
signing_key:
|
65
93
|
specification_version: 4
|
66
94
|
summary: Restrict system operations and file system access on OpenBSD
|
67
95
|
test_files: []
|