Module: Landlock
- Defined in:
- lib/landlock.rb,
lib/landlock/env.rb,
lib/landlock/errors.rb,
lib/landlock/native.rb,
lib/landlock/policy.rb,
lib/landlock/result.rb,
lib/landlock/rights.rb,
lib/landlock/runner.rb,
lib/landlock/rlimits.rb,
lib/landlock/version.rb,
lib/landlock/execution.rb,
lib/landlock/process_io.rb,
lib/landlock/validation.rb,
lib/landlock/runner/fork.rb,
lib/landlock/runner/native.rb,
ext/landlock/landlock.c
Defined Under Namespace
Modules: Env, Execution, Native, Policy, ProcessIO, ResultBehavior, Rlimits, Runner, Validation
Classes: CaptureResult, CommandError, Error, OutputTooLargeError, SyscallError
Constant Summary
collapse
- UnsupportedError =
Class.new(Error)
- FS_RIGHTS =
{
execute: ACCESS_FS_EXECUTE,
write_file: ACCESS_FS_WRITE_FILE,
read_file: ACCESS_FS_READ_FILE,
read_dir: ACCESS_FS_READ_DIR,
remove_dir: ACCESS_FS_REMOVE_DIR,
remove_file: ACCESS_FS_REMOVE_FILE,
make_char: ACCESS_FS_MAKE_CHAR,
make_dir: ACCESS_FS_MAKE_DIR,
make_reg: ACCESS_FS_MAKE_REG,
make_sock: ACCESS_FS_MAKE_SOCK,
make_fifo: ACCESS_FS_MAKE_FIFO,
make_block: ACCESS_FS_MAKE_BLOCK,
make_sym: ACCESS_FS_MAKE_SYM,
refer: ACCESS_FS_REFER,
truncate: ACCESS_FS_TRUNCATE,
ioctl_dev: ACCESS_FS_IOCTL_DEV
}.freeze
- NET_RIGHTS =
{ bind_tcp: ACCESS_NET_BIND_TCP, connect_tcp: ACCESS_NET_CONNECT_TCP }.freeze
- SCOPE_FLAGS =
{ abstract_unix_socket: SCOPE_ABSTRACT_UNIX_SOCKET, signal: SCOPE_SIGNAL }.freeze
- READ_RIGHTS =
%i[read_file read_dir].freeze
- EXEC_RIGHTS =
%i[execute read_file read_dir].freeze
- WRITE_RIGHTS =
%i[
read_file
read_dir
write_file
truncate
remove_dir
remove_file
make_char
make_dir
make_reg
make_sock
make_fifo
make_block
make_sym
refer
].freeze
- FILE_PATH_RIGHTS =
%i[execute write_file read_file truncate ioctl_dev].freeze
- VERSION =
"0.3"
- READ_CHUNK_BYTES =
16 * 1024
- PROCESS_POLL_SECONDS =
0.1
- STDIN_THREAD_JOIN_SECONDS =
0.1
- POST_TIMEOUT_DRAIN_SECONDS =
0.05
- ACCESS_FS_EXECUTE =
ULL2NUM(LANDLOCK_ACCESS_FS_EXECUTE)
- ACCESS_FS_WRITE_FILE =
ULL2NUM(LANDLOCK_ACCESS_FS_WRITE_FILE)
- ACCESS_FS_READ_FILE =
ULL2NUM(LANDLOCK_ACCESS_FS_READ_FILE)
- ACCESS_FS_READ_DIR =
ULL2NUM(LANDLOCK_ACCESS_FS_READ_DIR)
- ACCESS_FS_REMOVE_DIR =
ULL2NUM(LANDLOCK_ACCESS_FS_REMOVE_DIR)
- ACCESS_FS_REMOVE_FILE =
ULL2NUM(LANDLOCK_ACCESS_FS_REMOVE_FILE)
- ACCESS_FS_MAKE_CHAR =
ULL2NUM(LANDLOCK_ACCESS_FS_MAKE_CHAR)
- ACCESS_FS_MAKE_DIR =
ULL2NUM(LANDLOCK_ACCESS_FS_MAKE_DIR)
- ACCESS_FS_MAKE_REG =
ULL2NUM(LANDLOCK_ACCESS_FS_MAKE_REG)
- ACCESS_FS_MAKE_SOCK =
ULL2NUM(LANDLOCK_ACCESS_FS_MAKE_SOCK)
- ACCESS_FS_MAKE_FIFO =
ULL2NUM(LANDLOCK_ACCESS_FS_MAKE_FIFO)
- ACCESS_FS_MAKE_BLOCK =
ULL2NUM(LANDLOCK_ACCESS_FS_MAKE_BLOCK)
- ACCESS_FS_MAKE_SYM =
ULL2NUM(LANDLOCK_ACCESS_FS_MAKE_SYM)
- ACCESS_FS_REFER =
ULL2NUM(LANDLOCK_ACCESS_FS_REFER)
- ACCESS_FS_TRUNCATE =
ULL2NUM(LANDLOCK_ACCESS_FS_TRUNCATE)
- ACCESS_FS_IOCTL_DEV =
ULL2NUM(LANDLOCK_ACCESS_FS_IOCTL_DEV)
- ACCESS_NET_BIND_TCP =
ULL2NUM(LANDLOCK_ACCESS_NET_BIND_TCP)
- ACCESS_NET_CONNECT_TCP =
ULL2NUM(LANDLOCK_ACCESS_NET_CONNECT_TCP)
- SCOPE_ABSTRACT_UNIX_SOCKET =
ULL2NUM(LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET)
- SCOPE_SIGNAL =
ULL2NUM(LANDLOCK_SCOPE_SIGNAL)
Class Method Summary
collapse
Class Method Details
._add_net_rule(ruleset_fd, port, access_bits) ⇒ Object
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
# File 'ext/landlock/landlock.c', line 81
static VALUE rb_ll_add_net_rule(VALUE self, VALUE ruleset_fd, VALUE port, VALUE access_bits) {
unsigned long long p = NUM2ULL(port);
if (p > 65535ULL) {
rb_raise(rb_eArgError, "TCP port must be between 0 and 65535");
}
struct rb_landlock_net_port_attr rule;
memset(&rule, 0, sizeof(rule));
rule.allowed_access = NUM2ULL(access_bits);
rule.port = p;
long ret = ll_add_rule(NUM2INT(ruleset_fd), LANDLOCK_RULE_NET_PORT, &rule, 0);
if (ret < 0) {
raise_syscall_error("landlock_add_rule(net_port)");
}
return Qtrue;
}
|
._add_path_rule(ruleset_fd, path, access_bits) ⇒ Object
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
# File 'ext/landlock/landlock.c', line 56
static VALUE rb_ll_add_path_rule(VALUE self, VALUE ruleset_fd, VALUE path, VALUE access_bits) {
int ruleset = NUM2INT(ruleset_fd);
uint64_t allowed_access = NUM2ULL(access_bits);
Check_Type(path, T_STRING);
const char *cpath = StringValueCStr(path);
int parent_fd = open(cpath, O_PATH | O_CLOEXEC);
if (parent_fd < 0) {
raise_syscall_error("open");
}
struct rb_landlock_path_beneath_attr rule;
memset(&rule, 0, sizeof(rule));
rule.allowed_access = allowed_access;
rule.parent_fd = parent_fd;
long ret = ll_add_rule(ruleset, LANDLOCK_RULE_PATH_BENEATH, &rule, 0);
int saved_errno = errno;
close(parent_fd);
if (ret < 0) {
errno = saved_errno;
raise_syscall_error("landlock_add_rule(path_beneath)");
}
return Qtrue;
}
|
._close_fd(fd_value) ⇒ Object
116
117
118
119
120
121
122
|
# File 'ext/landlock/landlock.c', line 116
static VALUE rb_ll_close_fd(VALUE self, VALUE fd_value) {
int fd = NUM2INT(fd_value);
if (fd >= 0) {
close(fd);
}
return Qnil;
}
|
._create_ruleset(*args) ⇒ Object
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
# File 'ext/landlock/landlock.c', line 30
static VALUE rb_ll_create_ruleset(int argc, VALUE *argv, VALUE self) {
VALUE fs_bits, net_bits, scoped_bits;
rb_scan_args(argc, argv, "21", &fs_bits, &net_bits, &scoped_bits);
struct rb_landlock_ruleset_attr attr;
uint64_t handled_access_net = NUM2ULL(net_bits);
uint64_t scoped = NIL_P(scoped_bits) ? 0 : NUM2ULL(scoped_bits);
size_t attr_size = offsetof(struct rb_landlock_ruleset_attr, handled_access_net);
if (scoped != 0) {
attr_size = sizeof(struct rb_landlock_ruleset_attr);
} else if (handled_access_net != 0) {
attr_size = offsetof(struct rb_landlock_ruleset_attr, scoped);
}
memset(&attr, 0, sizeof(attr));
attr.handled_access_fs = NUM2ULL(fs_bits);
attr.handled_access_net = handled_access_net;
attr.scoped = scoped;
long fd = ll_create_ruleset(&attr, attr_size, 0);
if (fd < 0) {
raise_syscall_error("landlock_create_ruleset");
}
return INT2NUM(fd);
}
|
._restrict_self(ruleset_fd) ⇒ Object
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
# File 'ext/landlock/landlock.c', line 99
static VALUE rb_ll_restrict_self(VALUE self, VALUE ruleset_fd) {
#ifdef __linux__
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != 0) {
raise_syscall_error("prctl(PR_SET_NO_NEW_PRIVS)");
}
long ret = ll_restrict_self(NUM2INT(ruleset_fd), 0);
if (ret < 0) {
raise_syscall_error("landlock_restrict_self");
}
return Qtrue;
#else
errno = ENOSYS;
raise_syscall_error("landlock_restrict_self");
#endif
}
|
.abi_version ⇒ Object
19
20
21
22
23
24
25
26
27
28
|
# File 'ext/landlock/landlock.c', line 19
static VALUE rb_ll_abi_version(VALUE self) {
long abi = ll_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
if (abi < 0) {
if (errno == ENOSYS || errno == EOPNOTSUPP) {
return INT2FIX(0);
}
raise_syscall_error("landlock_create_ruleset");
}
return LONG2NUM(abi);
}
|
.capture ⇒ Object
35
36
37
|
# File 'lib/landlock.rb', line 35
def capture(...)
Execution.capture(...)
end
|
.capture! ⇒ Object
39
40
41
|
# File 'lib/landlock.rb', line 39
def capture!(...)
Execution.capture!(...)
end
|
.exec ⇒ Object
27
28
29
|
# File 'lib/landlock.rb', line 27
def exec(...)
Execution.exec(...)
end
|
.restrict! ⇒ Object
23
24
25
|
# File 'lib/landlock.rb', line 23
def restrict!(...)
Policy.restrict!(...)
end
|
.seccomp_deny_network! ⇒ Object
124
125
126
127
128
129
130
|
# File 'ext/landlock/landlock.c', line 124
static VALUE rb_ll_seccomp_deny_network(VALUE self) {
const char *error_message = "seccomp(SECCOMP_SET_MODE_FILTER)";
if (rb_landlock_seccomp_deny_network(&error_message) != 0) {
raise_syscall_error(error_message);
}
return Qtrue;
}
|
.spawn ⇒ Object
31
32
33
|
# File 'lib/landlock.rb', line 31
def spawn(...)
Execution.spawn(...)
end
|
.supported? ⇒ Boolean
17
18
19
20
21
|
# File 'lib/landlock.rb', line 17
def supported?
abi_version.positive?
rescue Error
false
end
|