Module: AgentJail::FFI::Landlock

Extended by:
FFI::Library
Defined in:
lib/agent_jail/ffi/landlock.rb

Overview

FFI bindings for the Linux Landlock LSM (kernel 5.13+). Uses raw syscalls via libc’s syscall(2) since Landlock has no libc wrappers.

Defined Under Namespace

Classes: PathBeneathAttr, RulesetAttr

Constant Summary collapse

ACCESS_FS_EXECUTE =

Landlock ABI v1 filesystem access rights

1 << 0
ACCESS_FS_WRITE_FILE =
1 << 1
ACCESS_FS_READ_FILE =
1 << 2
ACCESS_FS_READ_DIR =
1 << 3
ACCESS_FS_REMOVE_DIR =
1 << 4
ACCESS_FS_REMOVE_FILE =
1 << 5
ACCESS_FS_MAKE_CHAR =
1 << 6
ACCESS_FS_MAKE_DIR =
1 << 7
ACCESS_FS_MAKE_REG =
1 << 8
ACCESS_FS_MAKE_SOCK =
1 << 9
ACCESS_FS_MAKE_FIFO =
1 << 10
ACCESS_FS_MAKE_BLOCK =
1 << 11
ACCESS_FS_MAKE_SYM =
1 << 12
ACCESS_FS_READ_WRITE =

Composite access groups

ACCESS_FS_READ_FILE | ACCESS_FS_READ_DIR |
ACCESS_FS_WRITE_FILE | ACCESS_FS_REMOVE_FILE |
ACCESS_FS_MAKE_REG | ACCESS_FS_MAKE_DIR
ACCESS_FS_READ_ONLY =
ACCESS_FS_READ_FILE | ACCESS_FS_READ_DIR
ALL_ACCESS_FS =

All ABI v1 access bits — used in ruleset’s handled_access_fs

ACCESS_FS_EXECUTE | ACCESS_FS_WRITE_FILE | ACCESS_FS_READ_FILE |
ACCESS_FS_READ_DIR | ACCESS_FS_REMOVE_DIR | ACCESS_FS_REMOVE_FILE |
ACCESS_FS_MAKE_CHAR | ACCESS_FS_MAKE_DIR | ACCESS_FS_MAKE_REG |
ACCESS_FS_MAKE_SOCK | ACCESS_FS_MAKE_FIFO | ACCESS_FS_MAKE_BLOCK |
ACCESS_FS_MAKE_SYM
RULE_PATH_BENEATH =
1
SYS_LANDLOCK_CREATE_RULESET =

Syscall numbers (x86_64 Linux)

444
SYS_LANDLOCK_ADD_RULE =
445
SYS_LANDLOCK_RESTRICT_SELF =
446
PR_SET_NO_NEW_PRIVS =

prctl option

38

Class Method Summary collapse

Class Method Details

.add_path_rule(ruleset_fd, path_fd, allowed_access) ⇒ Object



76
77
78
79
80
81
82
83
84
85
# File 'lib/agent_jail/ffi/landlock.rb', line 76

def self.add_path_rule(ruleset_fd, path_fd, allowed_access)
  attr = PathBeneathAttr.new
  attr[:allowed_access] = allowed_access
  attr[:parent_fd] = path_fd
  syscall(SYS_LANDLOCK_ADD_RULE,
          :int, ruleset_fd,
          :uint32, RULE_PATH_BENEATH,
          :pointer, attr.to_ptr,
          :uint32, 0)
end

.create_ruleset(handled_access_fs) ⇒ Object



70
71
72
73
74
# File 'lib/agent_jail/ffi/landlock.rb', line 70

def self.create_ruleset(handled_access_fs)
  attr = RulesetAttr.new
  attr[:handled_access_fs] = handled_access_fs
  syscall(SYS_LANDLOCK_CREATE_RULESET, :pointer, attr.to_ptr, :size_t, attr.size, :uint32, 0)
end

.restrict_self(ruleset_fd) ⇒ Object



87
88
89
90
91
92
# File 'lib/agent_jail/ffi/landlock.rb', line 87

def self.restrict_self(ruleset_fd)
  prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)
  result = syscall(SYS_LANDLOCK_RESTRICT_SELF, :int, ruleset_fd, :uint32, 0)
  close(ruleset_fd)
  result
end