Handle newer landlock ABI versions for filesystem isolation
Dieser Commit ist enthalten in:
Ursprung
c9fdeb4a1d
Commit
bbc8193ea9
50
exile.c
50
exile.c
@ -1229,6 +1229,9 @@ static unsigned int exile_flags_to_landlock(unsigned int flags, int statmode)
|
|||||||
if(flags & EXILE_FS_ALLOW_ALL_WRITE)
|
if(flags & EXILE_FS_ALLOW_ALL_WRITE)
|
||||||
{
|
{
|
||||||
result |= LANDLOCK_ACCESS_FS_WRITE_FILE;
|
result |= LANDLOCK_ACCESS_FS_WRITE_FILE;
|
||||||
|
#ifdef LANDLOCK_ACCESS_FS_TRUNCATE
|
||||||
|
result |= LANDLOCK_ACCESS_FS_TRUNCATE;
|
||||||
|
#endif
|
||||||
if(S_ISDIR(statmode))
|
if(S_ISDIR(statmode))
|
||||||
{
|
{
|
||||||
result |= LANDLOCK_ACCESS_FS_REMOVE_DIR;
|
result |= LANDLOCK_ACCESS_FS_REMOVE_DIR;
|
||||||
@ -1238,6 +1241,9 @@ static unsigned int exile_flags_to_landlock(unsigned int flags, int statmode)
|
|||||||
result |= LANDLOCK_ACCESS_FS_MAKE_REG;
|
result |= LANDLOCK_ACCESS_FS_MAKE_REG;
|
||||||
result |= LANDLOCK_ACCESS_FS_MAKE_SOCK;
|
result |= LANDLOCK_ACCESS_FS_MAKE_SOCK;
|
||||||
result |= LANDLOCK_ACCESS_FS_MAKE_SYM;
|
result |= LANDLOCK_ACCESS_FS_MAKE_SYM;
|
||||||
|
#ifdef LANDLOCK_ACCESS_FS_REFER
|
||||||
|
result |= LANDLOCK_ACCESS_FS_REFER;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(flags & EXILE_FS_ALLOW_EXEC)
|
if(flags & EXILE_FS_ALLOW_EXEC)
|
||||||
@ -1304,15 +1310,42 @@ static unsigned int exile_flags_to_landlock(unsigned int flags, int statmode)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sets maximum values for the handled access fs... */
|
||||||
|
static int landlock_set_max_handled_access(struct landlock_ruleset_attr *ruleset)
|
||||||
|
{
|
||||||
|
int abi = landlock_create_ruleset(NULL, 0,
|
||||||
|
LANDLOCK_CREATE_RULESET_VERSION);
|
||||||
|
if(abi < 0)
|
||||||
|
{
|
||||||
|
EXILE_LOG_ERROR("Can't determine landlock ABI version\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ruleset->handled_access_net = 0;
|
||||||
|
if(abi == 1)
|
||||||
|
{
|
||||||
|
ruleset->handled_access_fs = ((LANDLOCK_ACCESS_FS_MAKE_SYM << 1) - 1);
|
||||||
|
}
|
||||||
|
if(abi == 2)
|
||||||
|
{
|
||||||
|
ruleset->handled_access_fs = ((LANDLOCK_ACCESS_FS_REFER << 1) - 1);
|
||||||
|
}
|
||||||
|
if(abi >= 3)
|
||||||
|
{
|
||||||
|
ruleset->handled_access_fs = ((LANDLOCK_ACCESS_FS_TRUNCATE << 1) - 1);
|
||||||
|
/* TODO: think about net */
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int landlock_prepare_ruleset(struct exile_path_policy *policies)
|
static int landlock_prepare_ruleset(struct exile_path_policy *policies)
|
||||||
{
|
{
|
||||||
int ruleset_fd = -1;
|
int ruleset_fd = -1;
|
||||||
struct landlock_ruleset_attr ruleset_attr = {0};
|
struct landlock_ruleset_attr ruleset_attr = {0};
|
||||||
/* We here want the maximum possible ruleset, so set the var to the max possible bitmask.
|
if(landlock_set_max_handled_access(&ruleset_attr) != 0)
|
||||||
Stolen/Adapted from: [linux src]/security/landlock/limits.h
|
{
|
||||||
*/
|
return -1;
|
||||||
ruleset_attr.handled_access_fs = ((LANDLOCK_ACCESS_FS_MAKE_SYM << 1) - 1);
|
}
|
||||||
|
|
||||||
ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
|
ruleset_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
|
||||||
if (ruleset_fd < 0)
|
if (ruleset_fd < 0)
|
||||||
{
|
{
|
||||||
@ -1339,6 +1372,13 @@ static int landlock_prepare_ruleset(struct exile_path_policy *policies)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
path_beneath.allowed_access = exile_flags_to_landlock(policy->policy, sb.st_mode);
|
path_beneath.allowed_access = exile_flags_to_landlock(policy->policy, sb.st_mode);
|
||||||
|
|
||||||
|
/* Required, so the .allowed_access fits .handled_access_fs of the ruleset.
|
||||||
|
* Needed for backwards compatibility, e. g. new binary compiled with new headers,
|
||||||
|
executed on a kernel with an older ABI version which does not have some constant defined...
|
||||||
|
*/
|
||||||
|
path_beneath.allowed_access &= ruleset_attr.handled_access_fs;
|
||||||
|
|
||||||
ret = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, &path_beneath, 0);
|
ret = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, &path_beneath, 0);
|
||||||
if(ret)
|
if(ret)
|
||||||
{
|
{
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren