2024-06-25 08:25:53 +02:00
|
|
|
## About
|
2017-05-24 17:34:00 +02:00
|
|
|
|
2024-06-26 23:16:04 +02:00
|
|
|
bsdcapsicum.rb provides Ruby bindings for
|
2024-06-25 17:26:01 +02:00
|
|
|
[capsicum(4)](https://man.freebsd.org/cgi/man.cgi?query=capsicum&apropos=0&sektion=4&format=html).
|
2017-05-24 02:18:05 +02:00
|
|
|
|
2024-06-25 08:57:49 +02:00
|
|
|
## Examples
|
2017-05-24 02:18:05 +02:00
|
|
|
|
2024-06-25 08:57:49 +02:00
|
|
|
__Capability mode__
|
2017-05-24 17:34:00 +02:00
|
|
|
|
2024-06-25 08:57:49 +02:00
|
|
|
A process can enter into capability mode by calling
|
2024-08-14 21:52:29 +02:00
|
|
|
the [BSD::Capsicum.enter!](http://0x1eef.github.io/x/bsdcapsicum.rb/BSD/Capsicum.html#enter!-instance_method)
|
|
|
|
method. After entering capability mode, the process has limited
|
|
|
|
abilities. File descriptors acquired before entering capability
|
|
|
|
mode remain accessible and unrestricted, but their capabilites
|
|
|
|
can be reduced. See the
|
2024-06-25 08:57:49 +02:00
|
|
|
[cap_enter(2)](https://man.freebsd.org/cgi/man.cgi?query=cap_enter&apropos=0&sektion=2&format=html)
|
2024-06-25 09:04:08 +02:00
|
|
|
manual page for more details:
|
2017-05-24 02:18:47 +02:00
|
|
|
|
|
|
|
```ruby
|
2024-06-25 09:11:12 +02:00
|
|
|
#!/usr/bin/env ruby
|
2024-06-25 08:25:53 +02:00
|
|
|
require "bsd/capsicum"
|
2024-06-25 04:36:09 +02:00
|
|
|
|
2024-06-27 10:36:37 +02:00
|
|
|
print "In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
|
|
|
|
print "Enter capability mode: ", (BSD::Capsicum.enter! ? "ok" : "error"), "\n"
|
|
|
|
print "In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
|
2024-06-25 04:36:09 +02:00
|
|
|
|
|
|
|
begin
|
|
|
|
File.new(File::NULL)
|
|
|
|
rescue Errno::ECAPMODE => ex
|
|
|
|
print "Error: #{ex.message} (#{ex.class})", "\n"
|
|
|
|
end
|
|
|
|
|
|
|
|
##
|
|
|
|
# In capability mode: no
|
|
|
|
# Enter capability mode: ok
|
|
|
|
# In capability mode: yes
|
|
|
|
# Error: Not permitted in capability mode @ rb_sysopen - /dev/null (Errno::ECAPMODE)
|
2017-05-24 02:18:47 +02:00
|
|
|
```
|
|
|
|
|
2024-07-12 15:52:25 +02:00
|
|
|
__Child process__
|
2017-05-24 02:18:47 +02:00
|
|
|
|
2024-06-25 08:57:49 +02:00
|
|
|
By spawning a child process and then entering capability mode, restrictions can be
|
|
|
|
limited to a child process (and its child processes, if any). This can be helpful in
|
|
|
|
an architecture where a parent process can spawn one or more child processes to handle
|
|
|
|
certain tasks but with restrictions in place:
|
2017-05-24 02:18:47 +02:00
|
|
|
|
|
|
|
```ruby
|
2024-06-25 09:11:12 +02:00
|
|
|
#!/usr/bin/env ruby
|
2024-06-25 08:25:53 +02:00
|
|
|
require "bsd/capsicum"
|
2024-06-25 05:23:16 +02:00
|
|
|
|
2024-06-27 10:36:37 +02:00
|
|
|
print "[parent] In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
|
2024-06-25 03:56:42 +02:00
|
|
|
fork do
|
2024-07-19 06:04:55 +02:00
|
|
|
print "[child] Enter capability mode: ", (BSD::Capsicum.enter! ? "ok" : "error"), "\n"
|
|
|
|
print "[child] In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
|
|
|
|
print "[child] Exit", "\n"
|
2017-05-24 02:18:47 +02:00
|
|
|
exit 42
|
|
|
|
end
|
2024-06-25 03:56:42 +02:00
|
|
|
Process.wait
|
2024-06-27 10:36:37 +02:00
|
|
|
print "[parent] In capability mode: ", (BSD::Capsicum.in_capability_mode? ? "yes" : "no"), "\n"
|
2017-05-24 02:18:47 +02:00
|
|
|
|
2024-06-25 05:23:16 +02:00
|
|
|
##
|
|
|
|
# [parent] In capability mode: no
|
2024-07-19 06:04:55 +02:00
|
|
|
# [child] Enter capability mode: ok
|
|
|
|
# [child] In capability mode: yes
|
|
|
|
# [child] Exit
|
2024-06-25 05:23:16 +02:00
|
|
|
# [parent] In capability mode: no
|
2017-05-24 02:18:47 +02:00
|
|
|
```
|
|
|
|
|
2024-06-27 05:36:33 +02:00
|
|
|
__Rights__
|
|
|
|
|
|
|
|
The
|
|
|
|
[BSD::Capsicum.set_rights!](http://0x1eef.github.io/x/bsdcapsicum.rb/BSD/Capsicum.html#set_rights!-instance_method)
|
|
|
|
method can reduce the capabilities of a file descriptor. The following
|
2024-06-27 10:09:13 +02:00
|
|
|
example obtains a file descriptor in a parent process (with full capabilities),
|
|
|
|
then limits the capabilities of the file descriptor
|
2024-06-27 05:36:33 +02:00
|
|
|
in a child process to allow only read operations. See the
|
|
|
|
[rights(4)](https://man.freebsd.org/cgi/man.cgi?query=rights&apropos=0&sektion=4&format=html)
|
|
|
|
man page for a full list of capabilities:
|
|
|
|
|
|
|
|
``` ruby
|
|
|
|
#!/usr/bin/env ruby
|
|
|
|
require "bsd/capsicum"
|
|
|
|
|
|
|
|
path = File.join(Dir.home, "bsdcapsicum.txt")
|
|
|
|
file = File.open(path, File::CREAT | File::TRUNC | File::RDWR)
|
|
|
|
file.sync = true
|
2024-06-27 10:09:13 +02:00
|
|
|
print "[parent] Obtain file descriptor (with all capabilities)", "\n"
|
2024-06-27 05:36:33 +02:00
|
|
|
fork do
|
|
|
|
BSD::Capsicum.set_rights!(file, %i[CAP_READ])
|
2024-07-19 06:04:55 +02:00
|
|
|
print "[child] Reduce capabilities to read", "\n"
|
2024-06-27 05:36:33 +02:00
|
|
|
|
|
|
|
file.gets
|
2024-07-19 06:04:55 +02:00
|
|
|
print "[child] Read OK", "\n"
|
2024-06-27 05:36:33 +02:00
|
|
|
|
|
|
|
begin
|
|
|
|
file.write "foo"
|
|
|
|
rescue Errno::ENOTCAPABLE => ex
|
2024-07-19 06:04:55 +02:00
|
|
|
print "[child] Error: #{ex.message} (#{ex.class})", "\n"
|
2024-06-27 05:36:33 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
Process.wait
|
|
|
|
file.write "[parent] Hello from #{Process.pid}", "\n"
|
2024-06-27 10:09:13 +02:00
|
|
|
print "[parent] Write OK", "\n"
|
2024-06-27 05:36:33 +02:00
|
|
|
|
|
|
|
##
|
2024-06-27 10:11:19 +02:00
|
|
|
# [parent] Obtain file descriptor (with all capabilities)
|
2024-07-19 06:04:55 +02:00
|
|
|
# [child] Reduce capabilities to read
|
|
|
|
# [child] Read OK
|
|
|
|
# [child] Error: Capabilities insufficient @ io_write - /home/user/bsdcapsicum.txt (Errno::ENOTCAPABLE)
|
2024-06-27 10:09:13 +02:00
|
|
|
# [parent] Write OK
|
2024-06-27 05:36:33 +02:00
|
|
|
```
|
|
|
|
|
2024-06-25 09:04:08 +02:00
|
|
|
## Documentation
|
|
|
|
|
|
|
|
A complete API reference is available at [0x1eef.github.io/x/bsdcapsicum.rb](https://0x1eef.github.io/x/bsdcapsicum.rb)
|
2017-05-24 02:18:05 +02:00
|
|
|
|
2024-06-25 08:57:49 +02:00
|
|
|
## Install
|
2017-05-24 02:18:05 +02:00
|
|
|
|
2024-06-25 08:57:49 +02:00
|
|
|
bsdcapsicum.rb is available via rubygems.org:
|
2017-05-24 17:34:00 +02:00
|
|
|
|
2024-06-25 08:57:49 +02:00
|
|
|
gem install bsdcapsicum.rb
|
2017-05-24 02:18:05 +02:00
|
|
|
|
2024-06-25 09:54:45 +02:00
|
|
|
## Sources
|
|
|
|
|
|
|
|
* [GitHub](https://github.com/0x1eef/bsdcapsicum.rb#readme)
|
2024-06-27 10:51:13 +02:00
|
|
|
* [GitLab](https://gitlab.com/0x1eef/bsdcapsicum.rb#about)
|
2024-07-08 19:11:45 +02:00
|
|
|
* [git.HardenedBSD.org/@0x1eef](https://git.hardenedbsd.org/0x1eef/bsdcapsicum.rb#about)
|
|
|
|
* [brew.bsd.cafe/@0x1eef](https://brew.bsd.cafe/0x1eef/bsdcapsicum.rb)
|
2024-06-25 09:54:45 +02:00
|
|
|
|
2024-06-25 08:57:49 +02:00
|
|
|
## See also
|
2017-05-24 02:18:05 +02:00
|
|
|
|
2024-06-25 09:04:08 +02:00
|
|
|
* [Freaky/ruby-capsicum](https://github.com/Freaky/ruby-capsicum) <br>
|
2024-06-25 08:57:49 +02:00
|
|
|
bsdcapsicum.rb is a fork of this project. It was a huge help both
|
|
|
|
in terms of code and documentation.
|
2017-05-24 02:18:05 +02:00
|
|
|
|
|
|
|
## License
|
|
|
|
|
2024-06-27 07:07:05 +02:00
|
|
|
bsdcapsicum.rb
|
|
|
|
<br>
|
|
|
|
[BSD Zero Clause](https://choosealicense.com/licenses/0bsd/)
|
|
|
|
<br>
|
|
|
|
See [LICENSE](./LICENSE)
|
|
|
|
<br><br>
|
|
|
|
ruby-capsicum
|
|
|
|
<br>
|
|
|
|
[Freaky/ruby-capsicum](https://github.com/Freaky/ruby-capsicum) is released
|
|
|
|
under the terms of the MIT license
|
|
|
|
<br>
|
|
|
|
See [LICENSE.ruby-capsicum](/.LICENSE-ruby-capsicum)
|