bsdcapsicum.rb 0.2.0 → 0.3.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
- data/README.md +21 -19
- data/lib/bsd/capsicum/constants.rb +4 -0
- data/lib/bsd/capsicum/ffi.rb +31 -29
- data/lib/bsd/capsicum/version.rb +1 -1
- data/lib/bsd/capsicum.rb +8 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68cc91e740a2c2e8586db3884729be9c4fcefe8de403876ff805ac2bdaa3575b
|
4
|
+
data.tar.gz: d71319a3f9a56b63faef409ea27647ea93796eedda15658ad28bf9a9cd395066
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94b898fee6872449599545d87fd4d52e9231b6e6d7424d58d3bfc7b22e97c84d5b10719821581bc590822e49464703503a284d9205def2ccba65670d300f97d6
|
7
|
+
data.tar.gz: d3d0649cf733bd07ed0e66ee9bf223dbdee5c89a54b609e35583964a216bbd3136f2bfdf0d1988edc705c004ac1a2781a00316f08fd23f639054d83a56637318
|
data/README.md
CHANGED
@@ -20,9 +20,9 @@ manual page for more details:
|
|
20
20
|
#!/usr/bin/env ruby
|
21
21
|
require "bsd/capsicum"
|
22
22
|
|
23
|
-
print "In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
|
24
|
-
print "Enter capability mode: ", BSD::Capsicum.enter! ? "ok" : "error", "\n"
|
25
|
-
print "In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
|
23
|
+
print "In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
|
24
|
+
print "Enter capability mode: ", (BSD::Capsicum.enter! ? "ok" : "error"), "\n"
|
25
|
+
print "In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
|
26
26
|
|
27
27
|
begin
|
28
28
|
File.new(File::NULL)
|
@@ -37,7 +37,7 @@ end
|
|
37
37
|
# Error: Not permitted in capability mode @ rb_sysopen - /dev/null (Errno::ECAPMODE)
|
38
38
|
```
|
39
39
|
|
40
|
-
|
40
|
+
__Child process__
|
41
41
|
|
42
42
|
By spawning a child process and then entering capability mode, restrictions can be
|
43
43
|
limited to a child process (and its child processes, if any). This can be helpful in
|
@@ -48,15 +48,15 @@ certain tasks but with restrictions in place:
|
|
48
48
|
#!/usr/bin/env ruby
|
49
49
|
require "bsd/capsicum"
|
50
50
|
|
51
|
-
print "[parent] In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
|
51
|
+
print "[parent] In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
|
52
52
|
fork do
|
53
|
-
print "[subprocess] Enter capability mode: ", BSD::Capsicum.enter! ? "ok" : "error", "\n"
|
54
|
-
print "[subprocess] In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
|
53
|
+
print "[subprocess] Enter capability mode: ", (BSD::Capsicum.enter! ? "ok" : "error"), "\n"
|
54
|
+
print "[subprocess] In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
|
55
55
|
print "[subprocess] Exit", "\n"
|
56
56
|
exit 42
|
57
57
|
end
|
58
58
|
Process.wait
|
59
|
-
print "[parent] In capability mode: ", BSD::Capsicum.in_capability_mode? ? "yes" : "no", "\n"
|
59
|
+
print "[parent] In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
|
60
60
|
|
61
61
|
##
|
62
62
|
# [parent] In capability mode: no
|
@@ -71,8 +71,8 @@ __Rights__
|
|
71
71
|
The
|
72
72
|
[BSD::Capsicum.set_rights!](http://0x1eef.github.io/x/bsdcapsicum.rb/BSD/Capsicum.html#set_rights!-instance_method)
|
73
73
|
method can reduce the capabilities of a file descriptor. The following
|
74
|
-
example obtains a file descriptor in a parent process (with
|
75
|
-
|
74
|
+
example obtains a file descriptor in a parent process (with full capabilities),
|
75
|
+
then limits the capabilities of the file descriptor
|
76
76
|
in a child process to allow only read operations. See the
|
77
77
|
[rights(4)](https://man.freebsd.org/cgi/man.cgi?query=rights&apropos=0&sektion=4&format=html)
|
78
78
|
man page for a full list of capabilities:
|
@@ -84,13 +84,13 @@ require "bsd/capsicum"
|
|
84
84
|
path = File.join(Dir.home, "bsdcapsicum.txt")
|
85
85
|
file = File.open(path, File::CREAT | File::TRUNC | File::RDWR)
|
86
86
|
file.sync = true
|
87
|
-
print "[parent]
|
87
|
+
print "[parent] Obtain file descriptor (with all capabilities)", "\n"
|
88
88
|
fork do
|
89
89
|
BSD::Capsicum.set_rights!(file, %i[CAP_READ])
|
90
|
-
print "[subprocess]
|
90
|
+
print "[subprocess] Reduce capabilities to read", "\n"
|
91
91
|
|
92
92
|
file.gets
|
93
|
-
print "[subprocess]
|
93
|
+
print "[subprocess] Read OK", "\n"
|
94
94
|
|
95
95
|
begin
|
96
96
|
file.write "foo"
|
@@ -100,14 +100,14 @@ fork do
|
|
100
100
|
end
|
101
101
|
Process.wait
|
102
102
|
file.write "[parent] Hello from #{Process.pid}", "\n"
|
103
|
-
print "[parent]
|
103
|
+
print "[parent] Write OK", "\n"
|
104
104
|
|
105
105
|
##
|
106
|
-
# [parent]
|
107
|
-
# [subprocess]
|
108
|
-
# [subprocess]
|
106
|
+
# [parent] Obtain file descriptor (with all capabilities)
|
107
|
+
# [subprocess] Reduce capabilities to read
|
108
|
+
# [subprocess] Read OK
|
109
109
|
# [subprocess] Error: Capabilities insufficient @ io_write - /home/user/bsdcapsicum.txt (Errno::ENOTCAPABLE)
|
110
|
-
# [parent]
|
110
|
+
# [parent] Write OK
|
111
111
|
```
|
112
112
|
|
113
113
|
## Documentation
|
@@ -123,7 +123,9 @@ bsdcapsicum.rb is available via rubygems.org:
|
|
123
123
|
## Sources
|
124
124
|
|
125
125
|
* [GitHub](https://github.com/0x1eef/bsdcapsicum.rb#readme)
|
126
|
-
* [
|
126
|
+
* [GitLab](https://gitlab.com/0x1eef/bsdcapsicum.rb#about)
|
127
|
+
* [git.HardenedBSD.org/@0x1eef](https://git.hardenedbsd.org/0x1eef/bsdcapsicum.rb#about)
|
128
|
+
* [brew.bsd.cafe/@0x1eef](https://brew.bsd.cafe/0x1eef/bsdcapsicum.rb)
|
127
129
|
|
128
130
|
## See also
|
129
131
|
|
data/lib/bsd/capsicum/ffi.rb
CHANGED
@@ -3,8 +3,16 @@
|
|
3
3
|
module BSD::Capsicum
|
4
4
|
module FFI
|
5
5
|
require "fiddle"
|
6
|
+
require "fiddle/import"
|
6
7
|
include Fiddle::Types
|
7
8
|
include Constants
|
9
|
+
extend Fiddle::Importer
|
10
|
+
dlload Dir["/lib/libc.*"].first
|
11
|
+
|
12
|
+
extern "int cap_getmode(u_int*)"
|
13
|
+
extern "int cap_enter(void)"
|
14
|
+
extern "int cap_rights_limit(int, const cap_rights_t*)"
|
15
|
+
extern "cap_rights_t* __cap_rights_init(int version, cap_rights_t*, ...)"
|
8
16
|
|
9
17
|
module_function
|
10
18
|
|
@@ -12,11 +20,7 @@ module BSD::Capsicum
|
|
12
20
|
# Provides a Ruby interface for cap_enter(2)
|
13
21
|
# @return [Integer]
|
14
22
|
def cap_enter
|
15
|
-
|
16
|
-
libc["cap_enter"],
|
17
|
-
[],
|
18
|
-
INT
|
19
|
-
).call
|
23
|
+
self["cap_enter"].call
|
20
24
|
end
|
21
25
|
|
22
26
|
##
|
@@ -24,45 +28,43 @@ module BSD::Capsicum
|
|
24
28
|
# @param [Fiddle::Pointer] uintp
|
25
29
|
# @return [Integer]
|
26
30
|
def cap_getmode(uintp)
|
27
|
-
|
28
|
-
libc["cap_getmode"],
|
29
|
-
[INTPTR_T],
|
30
|
-
INT
|
31
|
-
).call(uintp)
|
31
|
+
self["cap_getmode"].call(uintp)
|
32
32
|
end
|
33
33
|
|
34
34
|
##
|
35
35
|
# Provides a Ruby interface for cap_rights_limit(2)
|
36
36
|
# @param [Integer] fd
|
37
|
-
# @param [Fiddle::Pointer]
|
37
|
+
# @param [Fiddle::Pointer] rightsp
|
38
38
|
# @return [Integer]
|
39
|
-
def cap_rights_limit(fd,
|
40
|
-
|
41
|
-
libc["cap_rights_limit"],
|
42
|
-
[INT, VOIDP],
|
43
|
-
INT
|
44
|
-
).call(fd, rights)
|
39
|
+
def cap_rights_limit(fd, rightsp)
|
40
|
+
self["cap_rights_limit"].call(fd, rightsp)
|
45
41
|
end
|
46
42
|
|
47
43
|
##
|
48
44
|
# Provides a Ruby interface for cap_rights_init(2)
|
49
|
-
# @
|
45
|
+
# @see BSD::Capsicum::Constants See Constants for a full list of capabilities
|
46
|
+
# @param [Fiddle::Pointer] rightsp
|
47
|
+
# A pointer to initialize the `cap_rights_t` structure
|
48
|
+
# @param [Array<Symbol, Integer>] capabilities
|
49
|
+
# An allowed set of capabilities
|
50
50
|
# @return [Fiddle::Pointer]
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
51
|
+
# Returns a pointer to the structure `cap_rights_t`
|
52
|
+
def cap_rights_init(rightsp, *capabilities)
|
53
|
+
self["__cap_rights_init"].call(
|
54
|
+
CAP_RIGHTS_VERSION,
|
55
|
+
rightsp,
|
56
|
+
*capabilities.flat_map { |cap|
|
57
|
+
[ULONG_LONG, cap_all.include?(cap) ? const_get(cap) : cap]
|
58
|
+
}
|
59
|
+
)
|
60
60
|
end
|
61
61
|
|
62
62
|
##
|
63
63
|
# @api private
|
64
|
-
|
65
|
-
|
64
|
+
# @return [Array<Symbol>]
|
65
|
+
# Returns all known capabilities
|
66
|
+
def cap_all
|
67
|
+
@cap_all ||= Constants.constants.select { _1.to_s.start_with?("CAP_") }
|
66
68
|
end
|
67
69
|
end
|
68
70
|
private_constant :FFI
|
data/lib/bsd/capsicum/version.rb
CHANGED
data/lib/bsd/capsicum.rb
CHANGED
@@ -44,26 +44,27 @@ module BSD::Capsicum
|
|
44
44
|
alias_method :enter_capability_mode!, :enter!
|
45
45
|
|
46
46
|
##
|
47
|
-
#
|
47
|
+
# Limit the capabilities of a file descriptor
|
48
48
|
#
|
49
49
|
# @see https://man.freebsd.org/cgi/man.cgi?query=cap_rights_limit&apropos=0&sektion=2&format=html cap_rights_limit(2)
|
50
50
|
# @see BSD::Capsicum::Constants See Constants for a full list of capabilities
|
51
51
|
# @example
|
52
|
-
# #
|
52
|
+
# # Limit standard output capabilities to read and write
|
53
53
|
# BSD::Capsicum.set_rights!(STDOUT, %i[CAP_READ CAP_WRITE])
|
54
54
|
# @raise [SystemCallError]
|
55
55
|
# Might raise a subclass of SystemCallError
|
56
56
|
# @param [#to_i] io
|
57
57
|
# An IO object
|
58
|
-
# @param [Array<
|
58
|
+
# @param [Array<Symbol, Integer>] capabilities
|
59
59
|
# An allowed set of capabilities
|
60
60
|
# @return [Boolean]
|
61
61
|
# Returns true when successful
|
62
|
-
def set_rights!(io,
|
63
|
-
|
64
|
-
FFI.
|
62
|
+
def set_rights!(io, capabilities)
|
63
|
+
rightsp = Fiddle::Pointer.malloc(Constants::SIZEOF_CAP_RIGHTS_T)
|
64
|
+
FFI.cap_rights_init(rightsp, *capabilities)
|
65
|
+
FFI.cap_rights_limit(io.to_i, rightsp).zero? ||
|
65
66
|
raise(SystemCallError.new("cap_rights_limit", Fiddle.last_error))
|
66
67
|
ensure
|
67
|
-
|
68
|
+
rightsp.call_free
|
68
69
|
end
|
69
70
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bsdcapsicum.rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Hurst
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-07-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: fiddle
|