Skip to content

Commit c245fec

Browse files
authored
Merge pull request #6125 from kmk3/landlock-enforce
landlock: move commands into profile and add landlock.enforce
2 parents 46d70ca + 760f50f commit c245fec

15 files changed

+91
-153
lines changed

contrib/syntax/lists/profile_commands_arg0.list

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ keep-config-pulse
1212
keep-dev-shm
1313
keep-shell-rc
1414
keep-var-tmp
15-
landlock
15+
landlock.enforce
1616
machine-id
1717
memory-deny-write-execute
1818
netfilter

contrib/syntax/lists/profile_commands_arg1.list

-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ iprange
3030
join-or-start
3131
keep-fd
3232
landlock.execute
33-
landlock.proc
3433
landlock.read
3534
landlock.special
3635
landlock.write

etc/inc/landlock-common.inc

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# This file is overwritten during software install.
2+
# Persistent customizations should go in a .local file.
3+
include landlock-common.local
4+
5+
landlock.read / # whole system read
6+
landlock.read /proc
7+
landlock.special / # sockets etc.
8+
9+
# write access
10+
landlock.write ${HOME}
11+
landlock.write ${RUNUSER}
12+
landlock.write /dev
13+
landlock.write /proc
14+
landlock.write /run/shm
15+
landlock.write /tmp
16+
17+
# exec access
18+
## misc
19+
landlock.execute /opt
20+
landlock.execute /run/firejail # appimage and various firejail features
21+
## bin
22+
landlock.execute /bin
23+
landlock.execute /sbin
24+
landlock.execute /usr/bin
25+
landlock.execute /usr/sbin
26+
landlock.execute /usr/games
27+
landlock.execute /usr/local/bin
28+
landlock.execute /usr/local/sbin
29+
landlock.execute /usr/local/games
30+
## lib
31+
landlock.execute /lib
32+
landlock.execute /lib32
33+
landlock.execute /libx32
34+
landlock.execute /lib64
35+
landlock.execute /usr/lib
36+
landlock.execute /usr/lib32
37+
landlock.execute /usr/libx32
38+
landlock.execute /usr/lib64
39+
landlock.execute /usr/local/lib

etc/profile-a-l/default.profile

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ include disable-programs.inc
2222
#include whitelist-usr-share-common.inc
2323
#include whitelist-var-common.inc
2424

25+
include landlock-common.inc
26+
2527
#apparmor
2628
caps.drop all
2729
#ipc-namespace

etc/templates/profile.template

+7
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,13 @@ include globals.local
137137
#include whitelist-usr-share-common.inc
138138
#include whitelist-var-common.inc
139139

140+
# Landlock commands
141+
##landlock.read PATH
142+
##landlock.write PATH
143+
##landlock.special PATH
144+
##landlock.execute PATH
145+
#include landlock-common.inc
146+
140147
##allusers
141148
#apparmor
142149
#caps.drop all

src/bash_completion/firejail.bash_completion.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ _firejail()
4242
_filedir -d
4343
return 0
4444
;;
45-
--landlock)
45+
--landlock.enforce)
4646
return 0
4747
;;
4848
--landlock.read)

src/firejail/firejail.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,7 @@ extern int arg_overlay; // overlay option
293293
extern int arg_overlay_keep; // place overlay diff in a known directory
294294
extern int arg_overlay_reuse; // allow the reuse of overlays
295295

296-
extern int arg_landlock; // add basic Landlock rules
297-
extern int arg_landlock_proc; // 0 - no access; 1 -read-only; 2 - read-write
296+
extern int arg_landlock_enforce; // enforce the Landlock ruleset
298297

299298
extern int arg_seccomp; // enable default seccomp filter
300299
extern int arg_seccomp32; // enable default seccomp filter for 32 bit arch
@@ -973,7 +972,6 @@ int ll_read(const char *allowed_path);
973972
int ll_write(const char *allowed_path);
974973
int ll_special(const char *allowed_path);
975974
int ll_exec(const char *allowed_path);
976-
int ll_basic_system(void);
977975
int ll_restrict(uint32_t flags);
978976
void ll_add_profile(int type, const char *data);
979977
#endif /* HAVE_LANDLOCK */

src/firejail/landlock.c

+12-57
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ static int ll_create_full_ruleset(void) {
117117
return ruleset_fd;
118118
}
119119

120-
static int ll_fs(const char *allowed_path, const __u64 allowed_access,
121-
const char *caller) {
120+
static int _ll_fs(const char *allowed_path, const __u64 allowed_access,
121+
const char *caller) {
122122
if (!ll_is_supported())
123123
return 0;
124124

@@ -155,6 +155,16 @@ static int ll_fs(const char *allowed_path, const __u64 allowed_access,
155155
return error;
156156
}
157157

158+
// TODO: Add support for the ${PATH} macro.
159+
static int ll_fs(const char *allowed_path, const __u64 allowed_access,
160+
const char *caller) {
161+
char *expanded_path = expand_macros(allowed_path);
162+
int error = _ll_fs(expanded_path, allowed_access, caller);
163+
164+
free(expanded_path);
165+
return error;
166+
}
167+
158168
int ll_read(const char *allowed_path) {
159169
__u64 allowed_access =
160170
LANDLOCK_ACCESS_FS_READ_DIR |
@@ -192,58 +202,6 @@ int ll_exec(const char *allowed_path) {
192202
return ll_fs(allowed_path, allowed_access, __func__);
193203
}
194204

195-
int ll_basic_system(void) {
196-
assert(cfg.homedir);
197-
198-
if (!ll_is_supported())
199-
return 0;
200-
201-
if (ll_ruleset_fd == -1)
202-
ll_ruleset_fd = ll_create_full_ruleset();
203-
204-
int error;
205-
char *rundir;
206-
if (asprintf(&rundir, "/run/user/%d", getuid()) == -1)
207-
errExit("asprintf");
208-
209-
error =
210-
ll_read("/") || // whole system read
211-
ll_special("/") || // sockets etc.
212-
213-
ll_write("/tmp") || // write access
214-
ll_write("/dev") ||
215-
ll_write("/run/shm") ||
216-
ll_write(cfg.homedir) ||
217-
ll_write(rundir) ||
218-
219-
ll_exec("/opt") || // exec access
220-
ll_exec("/bin") ||
221-
ll_exec("/sbin") ||
222-
ll_exec("/lib") ||
223-
ll_exec("/lib32") ||
224-
ll_exec("/libx32") ||
225-
ll_exec("/lib64") ||
226-
ll_exec("/usr/bin") ||
227-
ll_exec("/usr/sbin") ||
228-
ll_exec("/usr/games") ||
229-
ll_exec("/usr/lib") ||
230-
ll_exec("/usr/lib32") ||
231-
ll_exec("/usr/libx32") ||
232-
ll_exec("/usr/lib64") ||
233-
ll_exec("/usr/local/bin") ||
234-
ll_exec("/usr/local/sbin") ||
235-
ll_exec("/usr/local/games") ||
236-
ll_exec("/usr/local/lib") ||
237-
ll_exec("/run/firejail"); // appimage and various firejail features
238-
239-
if (error) {
240-
fprintf(stderr, "Error: %s: failed to set --landlock rules\n",
241-
__func__);
242-
}
243-
free(rundir);
244-
return error;
245-
}
246-
247205
int ll_restrict(uint32_t flags) {
248206
if (!ll_is_supported())
249207
return 0;
@@ -293,9 +251,6 @@ void ll_add_profile(int type, const char *data) {
293251
assert(type < LL_MAX);
294252
assert(data);
295253

296-
if (!ll_is_supported())
297-
return;
298-
299254
while (*data == ' ' || *data == '\t')
300255
data++;
301256

src/firejail/main.c

+3-17
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ int arg_overlay = 0; // overlay option
7575
int arg_overlay_keep = 0; // place overlay diff in a known directory
7676
int arg_overlay_reuse = 0; // allow the reuse of overlays
7777

78-
int arg_landlock = 0; // add basic Landlock rules
79-
int arg_landlock_proc = 2; // 0 - no access; 1 -read-only; 2 - read-write
78+
int arg_landlock_enforce = 0; // enforce the Landlock ruleset
8079

8180
int arg_seccomp = 0; // enable default seccomp filter
8281
int arg_seccomp32 = 0; // enable default seccomp filter for 32 bit arch
@@ -1504,21 +1503,8 @@ int main(int argc, char **argv, char **envp) {
15041503
exit_err_feature("seccomp");
15051504
}
15061505
#ifdef HAVE_LANDLOCK
1507-
else if (strcmp(argv[i], "--landlock") == 0)
1508-
arg_landlock = 1;
1509-
else if (strncmp(argv[i], "--landlock.proc=", 16) == 0) {
1510-
if (strncmp(argv[i] + 16, "no", 2) == 0)
1511-
arg_landlock_proc = 0;
1512-
else if (strncmp(argv[i] + 16, "ro", 2) == 0)
1513-
arg_landlock_proc = 1;
1514-
else if (strncmp(argv[i] + 16, "rw", 2) == 0)
1515-
arg_landlock_proc = 2;
1516-
else {
1517-
fprintf(stderr, "Error: invalid landlock.proc value: %s\n",
1518-
argv[i] + 16);
1519-
exit(1);
1520-
}
1521-
}
1506+
else if (strncmp(argv[i], "--landlock.enforce", 18) == 0)
1507+
arg_landlock_enforce = 1;
15221508
else if (strncmp(argv[i], "--landlock.read=", 16) == 0)
15231509
ll_add_profile(LL_READ, argv[i] + 16);
15241510
else if (strncmp(argv[i], "--landlock.write=", 17) == 0)

src/firejail/profile.c

+3-18
Original file line numberDiff line numberDiff line change
@@ -1074,24 +1074,9 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
10741074
}
10751075

10761076
#ifdef HAVE_LANDLOCK
1077-
// Landlock ruleset paths
1078-
if (strcmp(ptr, "landlock") == 0) {
1079-
arg_landlock = 1;
1080-
return 0;
1081-
}
1082-
if (strncmp(ptr, "landlock.proc ", 14) == 0) {
1083-
if (strncmp(ptr + 14, "no", 2) == 0)
1084-
arg_landlock_proc = 0;
1085-
else if (strncmp(ptr + 14, "ro", 2) == 0)
1086-
arg_landlock_proc = 1;
1087-
else if (strncmp(ptr + 14, "rw", 2) == 0)
1088-
arg_landlock_proc = 2;
1089-
else {
1090-
fprintf(stderr, "Error: invalid landlock.proc value: %s\n",
1091-
ptr + 14);
1092-
exit(1);
1093-
}
1094-
return 0;
1077+
if (strncmp(ptr, "landlock.enforce", 16) == 0) {
1078+
arg_landlock_enforce = 1;
1079+
return 0;
10951080
}
10961081
if (strncmp(ptr, "landlock.read ", 14) == 0) {
10971082
ll_add_profile(LL_READ, ptr + 14);

src/firejail/sandbox.c

+4-11
Original file line numberDiff line numberDiff line change
@@ -520,21 +520,14 @@ void start_application(int no_sandbox, int fd, char *set_sandbox_status) {
520520
//****************************
521521
// Configure Landlock
522522
//****************************
523-
if (arg_landlock)
524-
ll_basic_system();
525-
526-
if (ll_get_fd() != -1) {
527-
if (arg_landlock_proc >= 1)
528-
ll_read("/proc/");
529-
if (arg_landlock_proc == 2)
530-
ll_write("/proc/");
531-
}
532-
533-
if (ll_restrict(0)) {
523+
if (arg_landlock_enforce && ll_restrict(0)) {
534524
// It isn't safe to continue if Landlock self-restriction was
535525
// enabled and the "landlock_restrict_self" syscall has failed.
536526
fprintf(stderr, "Error: ll_restrict() failed, exiting...\n");
537527
exit(1);
528+
} else {
529+
if (arg_debug)
530+
fprintf(stderr, "Not enforcing Landlock\n");
538531
}
539532
#endif
540533

src/firejail/usage.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,7 @@ static const char *const usage_str =
134134
" --keep-shell-rc - do not copy shell rc files from /etc/skel\n"
135135
" --keep-var-tmp - /var/tmp directory is untouched.\n"
136136
#ifdef HAVE_LANDLOCK
137-
" --landlock - add basic rules to the Landlock ruleset.\n"
138-
" --landlock.proc=no|ro|rw - add an access rule for /proc to the Landlock ruleset.\n"
137+
" --landlock.enforce - enforce the Landlock ruleset.\n"
139138
" --landlock.read=path - add a read access rule for the path to the Landlock ruleset.\n"
140139
" --landlock.write=path - add a write access rule for the path to the Landlock ruleset.\n"
141140
" --landlock.special=path - add an access rule for the path to the Landlock ruleset for creating block/char devices, named pipes and sockets.\n"

src/man/firejail-profile.5.in

+4-11
Original file line numberDiff line numberDiff line change
@@ -509,17 +509,10 @@ Blacklist all Linux capabilities.
509509
Whitelist given Linux capabilities.
510510
#ifdef HAVE_LANDLOCK
511511
.TP
512-
\fBlandlock
513-
Create a Landlock ruleset (if it doesn't already exist) and add basic access
514-
rules to it.
515-
.TP
516-
\fBlandlock.proc no|ro|rw
517-
Add an access rule for /proc directory (read-only if set to \fBro\fR and
518-
read-write if set to \fBrw\fR).
519-
The access rule for /proc is added after this directory is set up in the
520-
sandbox.
521-
Access rules for /proc set up with other Landlock-related profile options have
522-
no effect.
512+
\fBlandlock.enforce
513+
Enforce the Landlock ruleset.
514+
.PP
515+
Without it, the other Landlock commands have no effect.
523516
.TP
524517
\fBlandlock.read path
525518
Create a Landlock ruleset (if it doesn't already exist) and add a read access

0 commit comments

Comments
 (0)