2323#include < stdbool.h>
2424
2525#include " sandbox.h"
26+ #include " util.h"
2627
2728#ifndef landlock_create_ruleset
2829static inline int
@@ -51,20 +52,19 @@ static inline int landlock_restrict_self(const int ruleset_fd,
5152}
5253#endif
5354
54- const char * sandbox_level_one ()
55+ void sandbox_level_one ()
5556{
56- if (prctl (PR_SET_NO_NEW_PRIVS, 1 , 0 , 0 , 0 ) != 0 ) { return " Failed to restrict root privileges" ; }
57- return nullptr ;
57+ if (prctl (PR_SET_NO_NEW_PRIVS, 1 , 0 , 0 , 0 ) != 0 ) ABORT (" Failed to restrict root privileges" );
5858}
5959
60- const char * sandbox_level_two ()
60+ void sandbox_level_two ()
6161{
6262 int abi = landlock_create_ruleset (NULL , 0 , LANDLOCK_CREATE_RULESET_VERSION);
6363 if (abi < 0 )
6464 {
65- if (errno == ENOSYS) return " Landlock sandbox is not supported by the current kernel" ;
66- else if (errno == EOPNOTSUPP) return " Landlock sandbox is currently disabled" ;
67- else return " Landlock sandboxing not supported by your system for unknown reason " ;
65+ if (errno == ENOSYS) ABORT ( " Landlock sandbox is not supported by the current kernel" ) ;
66+ else if (errno == EOPNOTSUPP) ABORT ( " Landlock sandbox is currently disabled" ) ;
67+ else ABORT ( " Landlock sandboxing not supported by your system: %s " , strerror (errno)) ;
6868 }
6969 struct landlock_ruleset_attr ruleset_attr = {};
7070 // Prohibit things we never need to do:
@@ -73,43 +73,37 @@ const char* sandbox_level_two()
7373 ruleset_attr.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP;
7474#endif
7575 int ruleset_fd = landlock_create_ruleset (&ruleset_attr, sizeof (ruleset_attr), 0 );
76- if (ruleset_fd < 0 ) return " Failed to create landlock ruleset" ;
77- if (landlock_restrict_self (ruleset_fd, 0 )) { close (ruleset_fd); return " Failed to enforce landlock ruleset" ; }
76+ if (ruleset_fd < 0 ) ABORT ( " Failed to create landlock ruleset: %s " , strerror (errno)) ;
77+ if (landlock_restrict_self (ruleset_fd, 0 ) != 0 ) ABORT ( " Failed to enforce landlock ruleset: %s " , strerror (errno));
7878 close (ruleset_fd);
79+ }
7980
80- return nullptr ;
81+ static void sandbox_except_path (int ruleset_fd, const char * path, int access_flags)
82+ {
83+ struct landlock_path_beneath_attr path_beneath = {};
84+ path_beneath.allowed_access = access_flags;
85+ path_beneath.parent_fd = open (path, O_PATH | O_CLOEXEC);
86+ if (path_beneath.parent_fd < 0 ) ABORT (" Failed to add exception for an app path from sandbox restrictions: %s" , strerror (errno));
87+ if (landlock_add_rule (ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, &path_beneath, 0 ) != 0 ) ABORT (" Failed to add path exception to landlock sandbox ruleset: %s" , strerror (errno));
88+ close (path_beneath.parent_fd );
8189}
8290
83- const char * sandbox_level_three ()
91+ void sandbox_level_three ()
8492{
85- char path[255 ];
86- memset (path, 0 , sizeof (path));
87- const char * exception_path = getcwd (path, sizeof (path));
88- // Error would have been spammed during init, do not need to repeat it; if we got here, we decided to ignore it
89- if (landlock_create_ruleset (NULL , 0 , LANDLOCK_CREATE_RULESET_VERSION) < 0 ) return nullptr ;
9093 // Prohibit things we don't need during replay
9194 struct landlock_ruleset_attr ruleset_attr = {};
9295 ruleset_attr.handled_access_fs = LANDLOCK_ACCESS_FS_MAKE_SYM | LANDLOCK_ACCESS_FS_MAKE_DIR | LANDLOCK_ACCESS_FS_MAKE_REG | LANDLOCK_ACCESS_FS_REMOVE_DIR | LANDLOCK_ACCESS_FS_REMOVE_FILE | LANDLOCK_ACCESS_FS_WRITE_FILE;
9396 int ruleset_fd = landlock_create_ruleset (&ruleset_attr, sizeof (ruleset_attr), 0 );
94- if (ruleset_fd < 0 ) return " Failed to create landlock ruleset" ;
97+ if (ruleset_fd < 0 ) ABORT (" Failed to create landlock ruleset: %s" , strerror (errno));
98+
9599 // Set up exception path from current working directory
96- if (exception_path)
97- {
98- struct landlock_path_beneath_attr path_beneath = {};
99- path_beneath.allowed_access = LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_REMOVE_FILE | LANDLOCK_ACCESS_FS_MAKE_DIR | LANDLOCK_ACCESS_FS_REMOVE_DIR;
100- path_beneath.parent_fd = open (exception_path, O_PATH | O_CLOEXEC);
101- if (path_beneath.parent_fd < 0 ) { close (ruleset_fd); return " Failed to open app path" ; }
102- int err = landlock_add_rule (ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, &path_beneath, 0 );
103- if (err)
104- {
105- printf (" 1: %s\n " , strerror (errno));
106- close (ruleset_fd);
107- close (path_beneath.parent_fd );
108- return " Failed to add path exception to landlock sandbox ruleset" ;
109- }
110- close (path_beneath.parent_fd );
111- }
112- if (landlock_restrict_self (ruleset_fd, 0 )) { close (ruleset_fd); return " Failed to enforce landlock ruleset" ; }
100+ char path[255 ];
101+ memset (path, 0 , sizeof (path));
102+ const char * exception_path = getcwd (path, sizeof (path));
103+ sandbox_except_path (ruleset_fd, exception_path, LANDLOCK_ACCESS_FS_WRITE_FILE | LANDLOCK_ACCESS_FS_REMOVE_FILE | LANDLOCK_ACCESS_FS_MAKE_DIR | LANDLOCK_ACCESS_FS_REMOVE_DIR);
104+ sandbox_except_path (ruleset_fd, " /dev" , LANDLOCK_ACCESS_FS_WRITE_FILE);
105+
106+ if (landlock_restrict_self (ruleset_fd, 0 ) != 0 ) ABORT (" Failed to enforce landlock ruleset: %s" , strerror (errno));
107+
113108 close (ruleset_fd);
114- return nullptr ;
115109}
0 commit comments