mirror of https://github.com/omar-polo/gmid.git
landlock the server process
Trying to implement some landlock policies (rules?) where possible. The server process is, of course, the most dangerous process so start with that. The following should be equivalent to the unveil(2) call on OpenBSD: allows only to read files and directories inside the vhost roots. I'm assuming seccomp is enabled so I'm not trying to disallow actions such as LANDLOCK_ACCESS_FS_EXECUTE or LANDLOCK_ACCESS_FS_REMOVE_FILE which require syscalls that are already disallowed. I'm only trying to limit the damage that the currently allowed system calls can do. e.g. since write(2) is allowed, gmid could modify *any* file it has access to; this is now forbidden by landlock. There are still too many #ifdefs for my tastes, but it's still better than the seccomp code.
This commit is contained in:
parent
d85aa60208
commit
3499ce5a9a
99
sandbox.c
99
sandbox.c
|
@ -84,6 +84,10 @@ sandbox_logger_process(void)
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#if HAVE_LANDLOCK
|
||||
# include "landlock_shim.h"
|
||||
#endif
|
||||
|
||||
/* uncomment to enable debugging. ONLY FOR DEVELOPMENT */
|
||||
/* #define SC_DEBUG */
|
||||
|
||||
|
@ -416,9 +420,88 @@ sandbox_seccomp_catch_sigsys(void)
|
|||
}
|
||||
#endif /* SC_DEBUG */
|
||||
|
||||
#if HAVE_LANDLOCK
|
||||
static int
|
||||
server_landlock(void)
|
||||
{
|
||||
int fd, err;
|
||||
struct vhost *h;
|
||||
struct location *l;
|
||||
|
||||
/*
|
||||
* These are all the actions that we want to either allow or
|
||||
* disallow. Things like LANDLOCK_ACCESS_FS_EXECUTE are
|
||||
* omitted because are already handled by seccomp.
|
||||
*/
|
||||
struct landlock_ruleset_attr ruleset_attr = {
|
||||
.handled_access_fs = LANDLOCK_ACCESS_FS_WRITE_FILE |
|
||||
LANDLOCK_ACCESS_FS_READ_FILE |
|
||||
LANDLOCK_ACCESS_FS_READ_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,
|
||||
};
|
||||
|
||||
/*
|
||||
* These are all the actions allowed for the root directories
|
||||
* of the vhosts. All the other rules mentioned in
|
||||
* ruleset_attr and omitted here are implicitly disallowed.
|
||||
*/
|
||||
struct landlock_path_beneath_attr path_beneath = {
|
||||
.allowed_access = LANDLOCK_ACCESS_FS_READ_FILE |
|
||||
LANDLOCK_ACCESS_FS_READ_DIR,
|
||||
};
|
||||
|
||||
fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
|
||||
if (fd == -1) {
|
||||
switch (errno) {
|
||||
case ENOSYS:
|
||||
fatal("%s: failed to create ruleset. "
|
||||
"Landlock doesn't seem to be supported by the "
|
||||
"current kernel.", __func__);
|
||||
case EOPNOTSUPP:
|
||||
log_warn(NULL, "%s: failed to create ruleset. "
|
||||
"Landlock seems to be currently disabled; "
|
||||
"continuing without it.", __func__);
|
||||
return -1;
|
||||
default:
|
||||
fatal("%s: failed to create ruleset: %s",
|
||||
__func__, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(h, &hosts, vhosts) {
|
||||
TAILQ_FOREACH(l, &h->locations, locations) {
|
||||
if (l->dir == NULL)
|
||||
continue;
|
||||
|
||||
path_beneath.parent_fd = open(l->dir, O_PATH);
|
||||
if (path_beneath.parent_fd == -1)
|
||||
fatal("%s: can't open %s for landlock: %s",
|
||||
__func__, l->dir, strerror(errno));
|
||||
|
||||
err = landlock_add_rule(fd, LANDLOCK_RULE_PATH_BENEATH,
|
||||
&path_beneath, 0);
|
||||
if (err)
|
||||
fatal("%s: landlock_add_rule(%s) failed: %s",
|
||||
__func__, l->dir, strerror(errno));
|
||||
|
||||
close(path_beneath.parent_fd);
|
||||
}
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sandbox_server_process(void)
|
||||
{
|
||||
int fd;
|
||||
struct sock_fprog prog = {
|
||||
.len = (unsigned short) (sizeof(filter) / sizeof(filter[0])),
|
||||
.filter = filter,
|
||||
|
@ -428,10 +511,26 @@ sandbox_server_process(void)
|
|||
sandbox_seccomp_catch_sigsys();
|
||||
#endif
|
||||
|
||||
#if HAVE_LANDLOCK
|
||||
log_warn(NULL, "loading landlock...");
|
||||
fd = server_landlock();
|
||||
#else
|
||||
(void)fd; /* avoid unused var warning */
|
||||
#endif
|
||||
|
||||
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 HAVE_LANDLOCK
|
||||
if (fd != -1) {
|
||||
if (landlock_restrict_self(fd, 0))
|
||||
fatal("%s: landlock_restrict_self: %s",
|
||||
__func__, strerror(errno));
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) == -1)
|
||||
fatal("%s: prctl(PR_SET_SECCOMP): %s\n",
|
||||
__func__, strerror(errno));
|
||||
|
|
Loading…
Reference in New Issue