Class: Seccomp::Notify::Policy
- Inherits:
-
Object
- Object
- Seccomp::Notify::Policy
- Defined in:
- lib/seccomp/notify/policy.rb
Constant Summary collapse
- BOOTSTRAP_SYSCALLS =
%i[fcntl].freeze
- ALLOWED_FLAGS =
Constants::SECCOMP_FILTER_FLAG_LOG | Constants::SECCOMP_FILTER_FLAG_SPEC_ALLOW | Constants::SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV
- DEFAULTS =
{ allow: Constants::SECCOMP_RET_ALLOW, errno: Constants::SECCOMP_RET_ERRNO | Errno::EPERM::Errno, kill: Constants::SECCOMP_RET_KILL_PROCESS }.freeze
Instance Attribute Summary collapse
-
#default_action ⇒ Object
readonly
Returns the value of attribute default_action.
Instance Method Summary collapse
- #conditional_notifications(arch) ⇒ Object
- #decisions(arch) ⇒ Object
-
#deny(*names, errno: Errno::EPERM) ⇒ void
Rejects syscalls in the kernel without notifying the supervisor.
-
#deny_io_uring! ⇒ void
Denies io_uring setup so submitted I/O cannot bypass seccomp.
- #flags ⇒ Object
-
#initialize(default: :allow, deny_io_uring: true, flags: 0, &block) ⇒ Policy
constructor
A new instance of Policy.
- #notified?(name) ⇒ Boolean
-
#notify(*names) ⇒ void
Marks syscalls for supervisor notification.
-
#notify_if(name, argument:, mask:) ⇒ Object
Notifies only when one of the low 32 bits in a syscall argument is set.
Constructor Details
#initialize(default: :allow, deny_io_uring: true, flags: 0, &block) ⇒ Policy
Returns a new instance of Policy.
18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/seccomp/notify/policy.rb', line 18 def initialize(default: :allow, deny_io_uring: true, flags: 0, &block) @default_action = DEFAULTS.fetch(default) { raise InvalidPolicyError, "invalid default action: #{default.inspect}" } raise ArgumentError, "flags must be an integer" unless flags.is_a?(Integer) @flags = flags @notifications = [] @conditional_notifications = [] @denials = {} deny_io_uring! if deny_io_uring instance_eval(&block) if block validate! end |
Instance Attribute Details
#default_action ⇒ Object (readonly)
Returns the value of attribute default_action.
16 17 18 |
# File 'lib/seccomp/notify/policy.rb', line 16 def default_action @default_action end |
Instance Method Details
#conditional_notifications(arch) ⇒ Object
81 82 83 84 85 |
# File 'lib/seccomp/notify/policy.rb', line 81 def conditional_notifications(arch) @conditional_notifications.filter_map do |name, argument, mask| [Syscalls.number(name, arch), argument, mask] unless notified?(name) || @denials.key?(name) end end |
#decisions(arch) ⇒ Object
66 67 68 69 70 71 72 73 74 75 |
# File 'lib/seccomp/notify/policy.rb', line 66 def decisions(arch) validate! notified = @notifications.to_h { |name| [Syscalls.number(name, arch), Constants::SECCOMP_RET_USER_NOTIF] } denied = @denials.to_h { |name, errno| [Syscalls.number(name, arch), Constants::SECCOMP_RET_ERRNO | errno] } notified.merge(denied).tap do |decisions| BOOTSTRAP_SYSCALLS.each do |name| decisions[Syscalls.number(name, arch)] = Constants::SECCOMP_RET_ALLOW unless @default_action == Constants::SECCOMP_RET_ALLOW end end end |
#deny(*names, errno: Errno::EPERM) ⇒ void
This method returns an undefined value.
Rejects syscalls in the kernel without notifying the supervisor.
50 51 52 53 |
# File 'lib/seccomp/notify/policy.rb', line 50 def deny(*names, errno: Errno::EPERM) number = Constants.errno_number(errno) names.each { |name| @denials[name.to_sym] = number } end |
#deny_io_uring! ⇒ void
This method returns an undefined value.
Denies io_uring setup so submitted I/O cannot bypass seccomp.
58 59 60 |
# File 'lib/seccomp/notify/policy.rb', line 58 def deny_io_uring! deny(:io_uring_setup, errno: Errno::ENOSYS) end |
#flags ⇒ Object
62 63 64 |
# File 'lib/seccomp/notify/policy.rb', line 62 def flags @flags end |
#notified?(name) ⇒ Boolean
77 78 79 |
# File 'lib/seccomp/notify/policy.rb', line 77 def notified?(name) @notifications.include?(name.to_sym) end |
#notify(*names) ⇒ void
This method returns an undefined value.
Marks syscalls for supervisor notification.
34 35 36 |
# File 'lib/seccomp/notify/policy.rb', line 34 def notify(*names) @notifications.concat(names.map(&:to_sym)) end |
#notify_if(name, argument:, mask:) ⇒ Object
Notifies only when one of the low 32 bits in a syscall argument is set.
39 40 41 42 43 44 |
# File 'lib/seccomp/notify/policy.rb', line 39 def notify_if(name, argument:, mask:) raise ArgumentError, "argument must be between 0 and 5" unless (0..5).cover?(argument) raise ArgumentError, "mask must be between 1 and 0xffffffff" unless mask.is_a?(Integer) && (1..0xffff_ffff).cover?(mask) @conditional_notifications << [name.to_sym, argument, mask] end |