About

bsdcapsicum.rb provides Ruby bindings for capsicum(4) via fiddle.

Examples

“Capability mode”

A process can enter into capability mode by calling the BSD::Capsicum.enter_capability_mode! method. After entering capability mode, the process may only issue system calls operating on file descriptors or reading limited global system state.

File descriptors acquired before entering capability mode remain fully capable but their capabilites can be reduced. See the cap_enter(2) manual page for more details:

#!/usr/bin/env ruby
require "bsd/capsicum"

print "In capability mode: ", (BSD::Capsicum.capability_mode? ? "yes" : "no"), "\n"
BSD::Capsicum.enter_capability_mode!
print "Enter capability mode: ok", "\n"
print "In capability mode: ", (BSD::Capsicum.capability_mode? ? "yes" : "no"), "\n"

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)

File descriptor

The BSD::Capsicum.limit! method can reduce the capabilities of a file descriptor. The following example obtains a file descriptor in a parent process (with full capabilities), then limits the capabilities of the file descriptor in a child process to allow only read operations. See the rights(4) and cap_rights_limit(2) manual pages for more information:

#!/usr/bin/env ruby
require "bsd/capsicum"
require "tmpdir"

path = File.join(Dir.tmpdir, "bsdcapsicum.txt")
file = File.open(path, File::CREAT | File::TRUNC | File::RDWR)
file.sync = true
print "[parent] Obtain file descriptor (with full capabilities)", "\n"
fork do
  BSD::Capsicum.limit!(file, allow: %i[read])
  print "[child] Reduce capabilities to read", "\n"

  file.gets
  print "[child] Read OK", "\n"

  begin
    file.write "foo"
  rescue Errno::ENOTCAPABLE => ex
    print "[child] Error: #{ex.message} (#{ex.class})", "\n"
  end
end
Process.wait
file.write "[parent] Hello from #{Process.pid}", "\n"
print "[parent] Write OK", "\n"

##
# [parent] Obtain file descriptor (with full capabilities)
# [child] Reduce capabilities to read
# [child] Read OK
# [child] Error: Capabilities insufficient @ io_write - /tmp/bsdcapsicum.txt (Errno::ENOTCAPABLE)
# [parent] Write OK

Documentation

A complete API reference is available at 0x1eef.github.io/x/bsdcapsicum.rb

Install

bsdcapsicum.rb is available via rubygems.org:

gem install bsdcapsicum.rb

Sources

See also

  • Freaky/ruby-capsicum
    bsdcapsicum.rb is a fork of this project. It was a huge help both in terms of code and documentation.

Status

The following functions have an equvialent Ruby interface:

The following functions compliment cap_rights_limit(2) but have not yet been implemented:

License

bsdcapsicum.rb
BSD Zero Clause
See LICENSE

ruby-capsicum
Freaky/ruby-capsicum is released under the terms of the MIT license
See LICENSE.ruby-capsicum