Skip to content

Commit ab6bfc6

Browse files
committed
samples/landlock: Add FS quiet flag support to sandboxer
Signed-off-by: Tingmao Wang <[email protected]> --- Changes since v1: - Populate quiet_access_* in ruleset_attr - Increment ABI version - Added support for quiet net rules
1 parent 769e3c4 commit ab6bfc6

File tree

1 file changed

+51
-9
lines changed

1 file changed

+51
-9
lines changed

samples/landlock/sandboxer.c

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,10 @@ static inline int landlock_restrict_self(const int ruleset_fd,
5858

5959
#define ENV_FS_RO_NAME "LL_FS_RO"
6060
#define ENV_FS_RW_NAME "LL_FS_RW"
61+
#define ENV_FS_QUIET_NAME "LL_FS_QUIET"
6162
#define ENV_TCP_BIND_NAME "LL_TCP_BIND"
6263
#define ENV_TCP_CONNECT_NAME "LL_TCP_CONNECT"
64+
#define ENV_NET_QUIET_NAME "LL_NET_QUIET"
6365
#define ENV_SCOPED_NAME "LL_SCOPED"
6466
#define ENV_FORCE_LOG_NAME "LL_FORCE_LOG"
6567
#define ENV_DELIMITER ":"
@@ -116,7 +118,7 @@ static int parse_path(char *env_path, const char ***const path_list)
116118
/* clang-format on */
117119

118120
static int populate_ruleset_fs(const char *const env_var, const int ruleset_fd,
119-
const __u64 allowed_access)
121+
const __u64 allowed_access, bool quiet)
120122
{
121123
int num_paths, i, ret = 1;
122124
char *env_path_name;
@@ -166,7 +168,8 @@ static int populate_ruleset_fs(const char *const env_var, const int ruleset_fd,
166168
if (!S_ISDIR(statbuf.st_mode))
167169
path_beneath.allowed_access &= ACCESS_FILE;
168170
if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
169-
&path_beneath, 0)) {
171+
&path_beneath,
172+
quiet ? LANDLOCK_ADD_RULE_QUIET : 0)) {
170173
fprintf(stderr,
171174
"Failed to update the ruleset with \"%s\": %s\n",
172175
path_list[i], strerror(errno));
@@ -184,7 +187,7 @@ static int populate_ruleset_fs(const char *const env_var, const int ruleset_fd,
184187
}
185188

186189
static int populate_ruleset_net(const char *const env_var, const int ruleset_fd,
187-
const __u64 allowed_access)
190+
const __u64 allowed_access, bool quiet)
188191
{
189192
int ret = 1;
190193
char *env_port_name, *env_port_name_next, *strport;
@@ -212,7 +215,8 @@ static int populate_ruleset_net(const char *const env_var, const int ruleset_fd,
212215
}
213216
net_port.port = port;
214217
if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
215-
&net_port, 0)) {
218+
&net_port,
219+
quiet ? LANDLOCK_ADD_RULE_QUIET : 0)) {
216220
fprintf(stderr,
217221
"Failed to update the ruleset with port \"%llu\": %s\n",
218222
net_port.port, strerror(errno));
@@ -299,7 +303,7 @@ static bool check_ruleset_scope(const char *const env_var,
299303

300304
/* clang-format on */
301305

302-
#define LANDLOCK_ABI_LAST 7
306+
#define LANDLOCK_ABI_LAST 8
303307

304308
#define XSTR(s) #s
305309
#define STR(s) XSTR(s)
@@ -328,6 +332,8 @@ static const char help[] =
328332
"\n"
329333
"A sandboxer should not log denied access requests to avoid spamming logs, "
330334
"but to test audit we can set " ENV_FORCE_LOG_NAME "=1\n"
335+
ENV_FS_QUIET_NAME " and " ENV_NET_QUIET_NAME " can then be used to make access "
336+
"to some denied paths or network ports not trigger audit logging.\n"
331337
"\n"
332338
"Example:\n"
333339
ENV_FS_RO_NAME "=\"${PATH}:/lib:/usr:/proc:/etc:/dev/urandom\" "
@@ -357,7 +363,12 @@ int main(const int argc, char *const argv[], char *const *const envp)
357363
LANDLOCK_ACCESS_NET_CONNECT_TCP,
358364
.scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
359365
LANDLOCK_SCOPE_SIGNAL,
366+
.quiet_access_fs = 0,
367+
.quiet_access_net = 0,
368+
.quiet_scoped = 0,
360369
};
370+
371+
bool quiet_supported = true;
361372
int supported_restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON;
362373
int set_restrict_flags = 0;
363374

@@ -444,6 +455,11 @@ int main(const int argc, char *const argv[], char *const *const envp)
444455
"provided by ABI version %d (instead of %d).\n",
445456
LANDLOCK_ABI_LAST, abi);
446457
__attribute__((fallthrough));
458+
case 7:
459+
/* Don't add quiet flags for ABI < 8 later on */
460+
quiet_supported = false;
461+
462+
__attribute__((fallthrough));
447463
case LANDLOCK_ABI_LAST:
448464
break;
449465
default:
@@ -490,29 +506,55 @@ int main(const int argc, char *const argv[], char *const *const envp)
490506
unsetenv(ENV_FORCE_LOG_NAME);
491507
}
492508

509+
/*
510+
* Add quiet for fs/net handled access bits. Doing this alone has no
511+
* effect unless we later add quiet rules per FS_QUIET/NET_QUIET.
512+
*/
513+
if (quiet_supported) {
514+
ruleset_attr.quiet_access_fs = ruleset_attr.handled_access_fs;
515+
ruleset_attr.quiet_access_net = ruleset_attr.handled_access_net;
516+
}
517+
493518
ruleset_fd =
494519
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
495520
if (ruleset_fd < 0) {
496521
perror("Failed to create a ruleset");
497522
return 1;
498523
}
499524

500-
if (populate_ruleset_fs(ENV_FS_RO_NAME, ruleset_fd, access_fs_ro)) {
525+
if (populate_ruleset_fs(ENV_FS_RO_NAME, ruleset_fd, access_fs_ro,
526+
false)) {
501527
goto err_close_ruleset;
502528
}
503-
if (populate_ruleset_fs(ENV_FS_RW_NAME, ruleset_fd, access_fs_rw)) {
529+
if (populate_ruleset_fs(ENV_FS_RW_NAME, ruleset_fd, access_fs_rw,
530+
false)) {
504531
goto err_close_ruleset;
505532
}
533+
/* Don't require this env to be present */
534+
if (quiet_supported && getenv(ENV_FS_QUIET_NAME)) {
535+
if (populate_ruleset_fs(ENV_FS_QUIET_NAME, ruleset_fd, 0,
536+
true)) {
537+
goto err_close_ruleset;
538+
}
539+
}
506540

507541
if (populate_ruleset_net(ENV_TCP_BIND_NAME, ruleset_fd,
508-
LANDLOCK_ACCESS_NET_BIND_TCP)) {
542+
LANDLOCK_ACCESS_NET_BIND_TCP, false)) {
509543
goto err_close_ruleset;
510544
}
511545
if (populate_ruleset_net(ENV_TCP_CONNECT_NAME, ruleset_fd,
512-
LANDLOCK_ACCESS_NET_CONNECT_TCP)) {
546+
LANDLOCK_ACCESS_NET_CONNECT_TCP, false)) {
513547
goto err_close_ruleset;
514548
}
515549

550+
/* Don't require this env to be present */
551+
if (quiet_supported && getenv(ENV_NET_QUIET_NAME)) {
552+
if (populate_ruleset_net(ENV_NET_QUIET_NAME, ruleset_fd, 0,
553+
true)) {
554+
goto err_close_ruleset;
555+
}
556+
}
557+
516558
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
517559
perror("Failed to restrict privileges");
518560
goto err_close_ruleset;

0 commit comments

Comments
 (0)