commit b0be0653909864ac2ea070184f6fc4f0dcc62299 from: Omar Polo date: Sun Sep 19 17:08:12 2021 UTC landlock the logger process too Disallow everything landlock can handle. The logger process doesn't need any fs access (on OpenBSD it runs with pledge("stdio recvfd")). commit - 0ea22af2805935f4562fb537eb57d85809e70a84 commit + b0be0653909864ac2ea070184f6fc4f0dcc62299 blob - c2e028bea7d959d1dd2552894d425f16786fa7b4 blob + 456a9355077700c8b37c5fd219056b19c9e648d0 --- sandbox.c +++ sandbox.c @@ -506,7 +506,60 @@ server_landlock(void) close(path_beneath.parent_fd); } } + + return fd; +} + +static int +logger_landlock(void) +{ + int fd, err; + + /* + * These are all the possible actions. The logger receives + * files descriptor so it doesn't need *ANY* fs access. It's + * easier to remove FS access than come up with a seccomp + * filter. + */ + struct landlock_ruleset_attr ruleset_attr = { + .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE | + LANDLOCK_ACCESS_FS_WRITE_FILE | + LANDLOCK_ACCESS_FS_READ_FILE | + LANDLOCK_ACCESS_FS_READ_DIR | + LANDLOCK_ACCESS_FS_REMOVE_DIR | + LANDLOCK_ACCESS_FS_REMOVE_FILE | + 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, + }; + + /* + * Disallow every action. + */ + struct landlock_path_beneath_attr path_beneath = { + .allowed_access = 0, + }; + + fd = gmid_create_landlock_rs(&ruleset_attr, sizeof(ruleset_attr), 0); + if (fd == -1) + return -1; + path_beneath.parent_fd = open("/", O_PATH); + if (path_beneath.parent_fd == -1) + fatal("%s: can't open / for landlock: %s", + __func__, strerror(errno)); + + err = landlock_add_rule(fd, LANDLOCK_RULE_PATH_BENEATH, + &path_beneath, 0); + if (err) + fatal("%s: landlock_add_rule(/) failed: %s", + __func__, strerror(errno)); + close(path_beneath.parent_fd); + return fd; } #endif @@ -565,9 +618,30 @@ void sandbox_logger_process(void) { /* - * To be honest, here we could use a seccomp policy to only - * allow writev(2) and memory allocations. + * Here we could use a seccomp filter to allow only recvfd, + * write/writev and memory allocations, but syslog is a beast + * and I don't know what syscalls it could end up doing. + * Landlock is a simpler beast, use it to disallow any file + * sytsem access. */ + +#if HAVE_LANDLOCK + int fd; + + if ((fd = logger_landlock()) == -1) + return; + + if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) == -1) + fatal("%s: prctl(PR_SET_NO_NEW_PRIVS): %s", + __func__, strerror(errno)); + + if (landlock_restrict_self(fd, 0)) + fatal("%s: landlock_restrict_self: %s" + __func__, strerror(errno)); + + close(fd); +#endif + return; }