Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
netblue30 committed Oct 25, 2023
1 parent 1b53f6b commit be69206
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 141 deletions.
17 changes: 9 additions & 8 deletions src/firejail/firejail.h
Original file line number Diff line number Diff line change
Expand Up @@ -958,14 +958,15 @@ void oom_set(const char *oom_string);

// landlock.c
#ifdef HAVE_LANDLOCK
int landlock_create_ruleset(struct landlock_ruleset_attr *rsattr,size_t size,__u32 flags);
int landlock_add_rule(int fd,enum landlock_rule_type t,void *attr,__u32 flags);
int landlock_restrict_self(int fd,__u32 flags);
int create_full_ruleset();
int add_read_access_rule_by_path(int rset_fd,char *allowed_path);
int add_write_access_rule_by_path(int rset_fd,char *allowed_path);
int add_create_special_rule_by_path(int rset_fd,char *allowed_path);
int add_execute_rule_by_path(int rset_fd,char *allowed_path);
int ll_create_ruleset(struct landlock_ruleset_attr *rsattr,size_t size,__u32 flags);
int ll_add_rule(int fd,enum landlock_rule_type t,void *attr,__u32 flags);
int ll_restrict_self(int fd,__u32 flags);
int ll_create_full_ruleset();
int ll_add_read_access_rule_by_path(int rset_fd,char *allowed_path);
int ll_add_write_access_rule_by_path(int rset_fd,char *allowed_path);
int ll_add_create_special_rule_by_path(int rset_fd,char *allowed_path);
int ll_add_execute_rule_by_path(int rset_fd,char *allowed_path);
void ll_basic_system(void);
#endif

#endif
67 changes: 49 additions & 18 deletions src/firejail/landlock.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,23 @@
*/

#ifdef HAVE_LANDLOCK
#define _GNU_SOURCE
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include "firejail.h"
#include <fcntl.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/prctl.h>
#include <linux/prctl.h>
#include <linux/landlock.h>

int landlock_create_ruleset(struct landlock_ruleset_attr *rsattr,size_t size,__u32 flags) {
int ll_create_ruleset(struct landlock_ruleset_attr *rsattr,size_t size,__u32 flags) {
return syscall(__NR_landlock_create_ruleset,rsattr,size,flags);
}

int landlock_add_rule(int fd,enum landlock_rule_type t,void *attr,__u32 flags) {
int ll_add_rule(int fd,enum landlock_rule_type t,void *attr,__u32 flags) {
return syscall(__NR_landlock_add_rule,fd,t,attr,flags);
}

int landlock_restrict_self(int fd,__u32 flags) {
int ll_restrict_self(int fd,__u32 flags) {
prctl(PR_SET_NO_NEW_PRIVS,1,0,0,0);
int result = syscall(__NR_landlock_restrict_self,fd,flags);
if (result!=0) return result;
Expand All @@ -49,58 +45,93 @@ int landlock_restrict_self(int fd,__u32 flags) {
}
}

int create_full_ruleset() {
int ll_create_full_ruleset() {
struct landlock_ruleset_attr attr;
attr.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR | LANDLOCK_ACCESS_FS_WRITE_FILE |
LANDLOCK_ACCESS_FS_REMOVE_FILE | LANDLOCK_ACCESS_FS_REMOVE_DIR | LANDLOCK_ACCESS_FS_MAKE_CHAR | LANDLOCK_ACCESS_FS_MAKE_DIR |
LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_MAKE_SOCK | LANDLOCK_ACCESS_FS_MAKE_FIFO | LANDLOCK_ACCESS_FS_MAKE_BLOCK |
LANDLOCK_ACCESS_FS_MAKE_SYM | LANDLOCK_ACCESS_FS_EXECUTE;
return landlock_create_ruleset(&attr,sizeof(attr),0);
return ll_create_ruleset(&attr,sizeof(attr),0);
}

int add_read_access_rule_by_path(int rset_fd,char *allowed_path) {
int ll_add_read_access_rule_by_path(int rset_fd,char *allowed_path) {
int result;
int allowed_fd = open(allowed_path,O_PATH | O_CLOEXEC);
struct landlock_path_beneath_attr target;
target.parent_fd = allowed_fd;
target.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR;
result = landlock_add_rule(rset_fd,LANDLOCK_RULE_PATH_BENEATH,&target,0);
result = ll_add_rule(rset_fd,LANDLOCK_RULE_PATH_BENEATH,&target,0);
close(allowed_fd);
return result;
}

int add_write_access_rule_by_path(int rset_fd,char *allowed_path) {
int ll_add_write_access_rule_by_path(int rset_fd,char *allowed_path) {
int result;
int allowed_fd = open(allowed_path,O_PATH | O_CLOEXEC);
struct landlock_path_beneath_attr target;
target.parent_fd = allowed_fd;
target.allowed_access = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_REMOVE_FILE | LANDLOCK_ACCESS_FS_REMOVE_DIR |
LANDLOCK_ACCESS_FS_MAKE_CHAR | LANDLOCK_ACCESS_FS_MAKE_DIR | LANDLOCK_ACCESS_FS_MAKE_REG |
LANDLOCK_ACCESS_FS_MAKE_SYM;
result = landlock_add_rule(rset_fd,LANDLOCK_RULE_PATH_BENEATH,&target,0);
result = ll_add_rule(rset_fd,LANDLOCK_RULE_PATH_BENEATH,&target,0);
close(allowed_fd);
return result;
}

int add_create_special_rule_by_path(int rset_fd,char *allowed_path) {
int ll_add_create_special_rule_by_path(int rset_fd,char *allowed_path) {
int result;
int allowed_fd = open(allowed_path,O_PATH | O_CLOEXEC);
struct landlock_path_beneath_attr target;
target.parent_fd = allowed_fd;
target.allowed_access = LANDLOCK_ACCESS_FS_MAKE_SOCK | LANDLOCK_ACCESS_FS_MAKE_FIFO | LANDLOCK_ACCESS_FS_MAKE_BLOCK;
result = landlock_add_rule(rset_fd,LANDLOCK_RULE_PATH_BENEATH,&target,0);
result = ll_add_rule(rset_fd,LANDLOCK_RULE_PATH_BENEATH,&target,0);
close(allowed_fd);
return result;
}

int add_execute_rule_by_path(int rset_fd,char *allowed_path) {
int ll_add_execute_rule_by_path(int rset_fd,char *allowed_path) {
int result;
int allowed_fd = open(allowed_path,O_PATH | O_CLOEXEC);
struct landlock_path_beneath_attr target;
target.parent_fd = allowed_fd;
target.allowed_access = LANDLOCK_ACCESS_FS_EXECUTE;
result = landlock_add_rule(rset_fd,LANDLOCK_RULE_PATH_BENEATH,&target,0);
result = ll_add_rule(rset_fd,LANDLOCK_RULE_PATH_BENEATH,&target,0);
close(allowed_fd);
return result;
}

void ll_basic_system(void) {
if (arg_landlock == -1)
arg_landlock = ll_create_full_ruleset();

const char *home_dir = env_get("HOME");
int home_fd = open(home_dir,O_PATH | O_CLOEXEC);
struct landlock_path_beneath_attr target;
target.parent_fd = home_fd;
target.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR |
LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_REMOVE_FILE |
LANDLOCK_ACCESS_FS_REMOVE_DIR | LANDLOCK_ACCESS_FS_MAKE_CHAR |
LANDLOCK_ACCESS_FS_MAKE_DIR | LANDLOCK_ACCESS_FS_MAKE_REG |
LANDLOCK_ACCESS_FS_MAKE_SYM;
if (ll_add_rule(arg_landlock,LANDLOCK_RULE_PATH_BENEATH,&target,0)) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
close(home_fd);

if (ll_add_read_access_rule_by_path(arg_landlock, "/bin/") ||
ll_add_execute_rule_by_path(arg_landlock, "/bin/") ||
ll_add_read_access_rule_by_path(arg_landlock, "/dev/") ||
ll_add_write_access_rule_by_path(arg_landlock, "/dev/") ||
// ll_add_execute_rule_by_path(arg_landlock, "/dev/") ||
ll_add_read_access_rule_by_path(arg_landlock, "/etc/") ||
ll_add_read_access_rule_by_path(arg_landlock, "/lib/") ||
ll_add_execute_rule_by_path(arg_landlock, "/lib/") ||
ll_add_read_access_rule_by_path(arg_landlock, "/opt/") ||
ll_add_execute_rule_by_path(arg_landlock, "/opt/") ||
ll_add_read_access_rule_by_path(arg_landlock, "/usr/") ||
ll_add_execute_rule_by_path(arg_landlock, "/usr/") ||
ll_add_read_access_rule_by_path(arg_landlock, "/var/"))
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}

#endif
71 changes: 11 additions & 60 deletions src/firejail/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ int just_run_the_shell = 0;
int arg_netlock = 0;
int arg_restrict_namespaces = 0;
int arg_landlock = -1;
int arg_landlock_proc = 0;
int arg_landlock_proc = 2; // 0 - no access; 1 -read-only; 2 - read-write

int parent_to_child_fds[2];
int child_to_parent_fds[2];
Expand Down Expand Up @@ -1503,83 +1503,34 @@ int main(int argc, char **argv, char **envp) {
exit_err_feature("seccomp");
}
#ifdef HAVE_LANDLOCK
else if (strcmp(argv[i], "--landlock") == 0) {
if (arg_landlock == -1) arg_landlock = create_full_ruleset();

const char *home_dir = env_get("HOME");
int home_fd = open(home_dir,O_PATH | O_CLOEXEC);
struct landlock_path_beneath_attr target;
target.parent_fd = home_fd;
target.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR |
LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_REMOVE_FILE |
LANDLOCK_ACCESS_FS_REMOVE_DIR | LANDLOCK_ACCESS_FS_MAKE_CHAR |
LANDLOCK_ACCESS_FS_MAKE_DIR | LANDLOCK_ACCESS_FS_MAKE_REG |
LANDLOCK_ACCESS_FS_MAKE_SYM;
if (landlock_add_rule(arg_landlock,LANDLOCK_RULE_PATH_BENEATH,&target,0)) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
close(home_fd);

if (add_read_access_rule_by_path(arg_landlock, "/bin/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_execute_rule_by_path(arg_landlock, "/bin/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/dev/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/etc/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/lib/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_execute_rule_by_path(arg_landlock, "/lib/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/opt/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_execute_rule_by_path(arg_landlock, "/opt/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/usr/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_execute_rule_by_path(arg_landlock, "/usr/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/var/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
}
else if (strcmp(argv[i], "--landlock") == 0)
ll_basic_system();
else if (strncmp(argv[i], "--landlock.proc=", 16) == 0) {
if (strncmp(argv[i]+16, "no", 2) == 0) arg_landlock_proc = 0;
else if (strncmp(argv[i]+16, "ro", 2) == 0) arg_landlock_proc = 1;
else if (strncmp(argv[i]+16, "rw", 2) == 0) arg_landlock_proc = 2;
}
else if (strncmp(argv[i], "--landlock.read=", 16) == 0) {
if (arg_landlock == -1) arg_landlock = create_full_ruleset();
if (add_read_access_rule_by_path(arg_landlock, argv[i]+16)) {
if (arg_landlock == -1) arg_landlock = ll_create_full_ruleset();
if (ll_add_read_access_rule_by_path(arg_landlock, argv[i]+16)) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
}
else if (strncmp(argv[i], "--landlock.write=", 17) == 0) {
if (arg_landlock == -1) arg_landlock = create_full_ruleset();
if (add_write_access_rule_by_path(arg_landlock, argv[i]+17)) {
if (arg_landlock == -1) arg_landlock = ll_create_full_ruleset();
if (ll_add_write_access_rule_by_path(arg_landlock, argv[i]+17)) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
}
else if (strncmp(argv[i], "--landlock.special=", 17) == 0) {
if (arg_landlock == -1) arg_landlock = create_full_ruleset();
if (add_create_special_rule_by_path(arg_landlock, argv[i]+17)) {
if (arg_landlock == -1) arg_landlock = ll_create_full_ruleset();
if (ll_add_create_special_rule_by_path(arg_landlock, argv[i]+17)) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
}
else if (strncmp(argv[i], "--landlock.execute=", 19) == 0) {
if (arg_landlock == -1) arg_landlock = create_full_ruleset();
if (add_execute_rule_by_path(arg_landlock, argv[i]+19)) {
if (arg_landlock == -1) arg_landlock = ll_create_full_ruleset();
if (ll_add_execute_rule_by_path(arg_landlock, argv[i]+19)) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
}
Expand Down
62 changes: 10 additions & 52 deletions src/firejail/profile.c
Original file line number Diff line number Diff line change
Expand Up @@ -1080,81 +1080,39 @@ int profile_check_line(char *ptr, int lineno, const char *fname) {
#ifdef HAVE_LANDLOCK
// Landlock ruleset paths
if (strcmp(ptr, "landlock") == 0) {
if (arg_landlock == -1) arg_landlock = create_full_ruleset();
const char *home_dir = env_get("HOME");
int home_fd = open(home_dir,O_PATH | O_CLOEXEC);
struct landlock_path_beneath_attr target;
target.parent_fd = home_fd;
target.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR | LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_REMOVE_FILE | LANDLOCK_ACCESS_FS_REMOVE_DIR | LANDLOCK_ACCESS_FS_MAKE_CHAR | LANDLOCK_ACCESS_FS_MAKE_DIR | LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_MAKE_SYM;
if (landlock_add_rule(arg_landlock,LANDLOCK_RULE_PATH_BENEATH,&target,0)) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
close(home_fd);
if (add_read_access_rule_by_path(arg_landlock, "/bin/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_execute_rule_by_path(arg_landlock, "/bin/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/dev/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/etc/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/lib/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_execute_rule_by_path(arg_landlock, "/lib/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/opt/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_execute_rule_by_path(arg_landlock, "/opt/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/usr/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_execute_rule_by_path(arg_landlock, "/usr/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
if (add_read_access_rule_by_path(arg_landlock, "/var/")) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
ll_basic_system();
return 0;
}
if (strncmp(ptr, "landlock.proc ", 14) == 0) {
if (strncmp(ptr+14, "no", 2) == 0) arg_landlock_proc = 0;
else if (strncmp(ptr+14, "ro", 2) == 0) arg_landlock_proc = 1;
else if (strncmp(ptr+14, "rw", 2) == 0) arg_landlock_proc = 2;
return 0;
}
}
if (strncmp(ptr, "landlock.read ", 14) == 0) {
if (arg_landlock == -1) arg_landlock = create_full_ruleset();
if (add_read_access_rule_by_path(arg_landlock, ptr+14)) {
if (arg_landlock == -1) arg_landlock = ll_create_full_ruleset();
if (ll_add_read_access_rule_by_path(arg_landlock, ptr+14)) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
return 0;
}
if (strncmp(ptr, "landlock.write ", 15) == 0) {
if (arg_landlock == -1) arg_landlock = create_full_ruleset();
if (add_write_access_rule_by_path(arg_landlock, ptr+15)) {
if (arg_landlock == -1) arg_landlock = ll_create_full_ruleset();
if (ll_add_write_access_rule_by_path(arg_landlock, ptr+15)) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
return 0;
}
if (strncmp(ptr, "landlock.special ", 26) == 0) {
if (arg_landlock == -1) arg_landlock = create_full_ruleset();
if (add_create_special_rule_by_path(arg_landlock, ptr+26)) {
if (arg_landlock == -1) arg_landlock = ll_create_full_ruleset();
if (ll_add_create_special_rule_by_path(arg_landlock, ptr+26)) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
return 0;
}
if (strncmp(ptr, "landlock.execute ", 17) == 0) {
if (arg_landlock == -1) arg_landlock = create_full_ruleset();
if (add_execute_rule_by_path(arg_landlock, ptr+17)) {
if (arg_landlock == -1) arg_landlock = ll_create_full_ruleset();
if (ll_add_execute_rule_by_path(arg_landlock, ptr+17)) {
fprintf(stderr,"An error has occured while adding a rule to the Landlock ruleset.\n");
}
return 0;
Expand Down
6 changes: 3 additions & 3 deletions src/firejail/sandbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ void start_application(int no_sandbox, int fd, char *set_sandbox_status) {
#ifdef HAVE_LANDLOCK
// set Landlock
if (arg_landlock >= 0) {
if (landlock_restrict_self(arg_landlock,0)) {
if (ll_restrict_self(arg_landlock,0)) {
fprintf(stderr,"An error has occured while enabling Landlock self-restriction. Exiting...\n");
exit(1); // it isn't safe to continue if Landlock self-restriction was enabled and the "landlock_restrict_self" syscall has failed
}
Expand Down Expand Up @@ -1017,9 +1017,9 @@ int sandbox(void* sandbox_arg) {
#ifdef HAVE_LANDLOCK
if (arg_landlock > -1) {
if (arg_landlock_proc >= 1)
add_read_access_rule_by_path(arg_landlock, "/proc/");
ll_add_read_access_rule_by_path(arg_landlock, "/proc/");
if (arg_landlock_proc == 2)
add_write_access_rule_by_path(arg_landlock, "/proc/");
ll_add_write_access_rule_by_path(arg_landlock, "/proc/");
}
#endif
//****************************
Expand Down

0 comments on commit be69206

Please sign in to comment.