Skip to content

Commit 76b902f

Browse files
committed
samples/landlock: Add support for file reparenting
Add LANDLOCK_ACCESS_FS_REFER to the "roughly write" access rights and leverage the Landlock ABI version to only try to enforce it if it is supported by the running kernel. Reviewed-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Mickaël Salaün <mic@digikod.net> Link: https://lore.kernel.org/r/20220506161102.525323-10-mic@digikod.net
1 parent f4056b9 commit 76b902f

1 file changed

Lines changed: 27 additions & 13 deletions

File tree

samples/landlock/sandboxer.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -159,18 +159,23 @@ static int populate_ruleset(const char *const env_var, const int ruleset_fd,
159159
LANDLOCK_ACCESS_FS_MAKE_SOCK | \
160160
LANDLOCK_ACCESS_FS_MAKE_FIFO | \
161161
LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
162-
LANDLOCK_ACCESS_FS_MAKE_SYM)
162+
LANDLOCK_ACCESS_FS_MAKE_SYM | \
163+
LANDLOCK_ACCESS_FS_REFER)
164+
165+
#define ACCESS_ABI_2 ( \
166+
LANDLOCK_ACCESS_FS_REFER)
163167

164168
/* clang-format on */
165169

166170
int main(const int argc, char *const argv[], char *const *const envp)
167171
{
168172
const char *cmd_path;
169173
char *const *cmd_argv;
170-
int ruleset_fd;
174+
int ruleset_fd, abi;
175+
__u64 access_fs_ro = ACCESS_FS_ROUGHLY_READ,
176+
access_fs_rw = ACCESS_FS_ROUGHLY_READ | ACCESS_FS_ROUGHLY_WRITE;
171177
struct landlock_ruleset_attr ruleset_attr = {
172-
.handled_access_fs = ACCESS_FS_ROUGHLY_READ |
173-
ACCESS_FS_ROUGHLY_WRITE,
178+
.handled_access_fs = access_fs_rw,
174179
};
175180

176181
if (argc < 2) {
@@ -196,12 +201,11 @@ int main(const int argc, char *const argv[], char *const *const envp)
196201
return 1;
197202
}
198203

199-
ruleset_fd =
200-
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
201-
if (ruleset_fd < 0) {
204+
abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
205+
if (abi < 0) {
202206
const int err = errno;
203207

204-
perror("Failed to create a ruleset");
208+
perror("Failed to check Landlock compatibility");
205209
switch (err) {
206210
case ENOSYS:
207211
fprintf(stderr,
@@ -221,13 +225,23 @@ int main(const int argc, char *const argv[], char *const *const envp)
221225
}
222226
return 1;
223227
}
224-
if (populate_ruleset(ENV_FS_RO_NAME, ruleset_fd,
225-
ACCESS_FS_ROUGHLY_READ)) {
228+
/* Best-effort security. */
229+
if (abi < 2) {
230+
ruleset_attr.handled_access_fs &= ~ACCESS_ABI_2;
231+
access_fs_ro &= ~ACCESS_ABI_2;
232+
access_fs_rw &= ~ACCESS_ABI_2;
233+
}
234+
235+
ruleset_fd =
236+
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
237+
if (ruleset_fd < 0) {
238+
perror("Failed to create a ruleset");
239+
return 1;
240+
}
241+
if (populate_ruleset(ENV_FS_RO_NAME, ruleset_fd, access_fs_ro)) {
226242
goto err_close_ruleset;
227243
}
228-
if (populate_ruleset(ENV_FS_RW_NAME, ruleset_fd,
229-
ACCESS_FS_ROUGHLY_READ |
230-
ACCESS_FS_ROUGHLY_WRITE)) {
244+
if (populate_ruleset(ENV_FS_RW_NAME, ruleset_fd, access_fs_rw)) {
231245
goto err_close_ruleset;
232246
}
233247
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {

0 commit comments

Comments
 (0)