Introduce flags indicating errors to catch non-checked return codes
Certain functions can fail before we execute exile_enable_policy(). While the return code should be checked, it's easily forgotten. For most users, checking just the exile_enable_policy() return code should suffice. exile_append_path_policies(): Add check whether a path exists. If not, set the error flag. This also allows an early exit, allowing to cleanly handle the case when a path does not exist. Previously, this was only caught during activation, and a failure there is generally undefined.
This commit is contained in:
parent
fd4dfb12f0
commit
3780509078
22
exile.h
22
exile.h
@ -328,6 +328,11 @@ is thus up to the default policy */
|
|||||||
|
|
||||||
|
|
||||||
#define EXILE_ARGFILTERS_COUNT 60
|
#define EXILE_ARGFILTERS_COUNT 60
|
||||||
|
|
||||||
|
|
||||||
|
#define EXILE_FLAG_ADD_PATH_POLICY_FAIL (1u<<1)
|
||||||
|
#define EXILE_FLAG_ADD_SYSCALL_POLICY_FAIL (1u<<2)
|
||||||
|
|
||||||
struct exile_syscall_policy
|
struct exile_syscall_policy
|
||||||
{
|
{
|
||||||
struct sock_filter argfilters[EXILE_ARGFILTERS_COUNT];
|
struct sock_filter argfilters[EXILE_ARGFILTERS_COUNT];
|
||||||
@ -364,6 +369,7 @@ struct exile_policy
|
|||||||
struct exile_syscall_policy *syscall_policies;
|
struct exile_syscall_policy *syscall_policies;
|
||||||
struct exile_syscall_policy **syscall_policies_tail;
|
struct exile_syscall_policy **syscall_policies_tail;
|
||||||
|
|
||||||
|
uint32_t exile_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -662,6 +668,7 @@ int exile_append_syscall_policy(struct exile_policy *exile_policy, long syscall,
|
|||||||
if(newpolicy == NULL)
|
if(newpolicy == NULL)
|
||||||
{
|
{
|
||||||
EXILE_LOG_ERROR("Failed to allocate memory for syscall policy\n");
|
EXILE_LOG_ERROR("Failed to allocate memory for syscall policy\n");
|
||||||
|
exile_policy->exile_flags |= EXILE_FLAG_ADD_SYSCALL_POLICY_FAIL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
newpolicy->policy = syscall_policy;
|
newpolicy->policy = syscall_policy;
|
||||||
@ -670,6 +677,7 @@ int exile_append_syscall_policy(struct exile_policy *exile_policy, long syscall,
|
|||||||
if(n > EXILE_ARGFILTERS_COUNT)
|
if(n > EXILE_ARGFILTERS_COUNT)
|
||||||
{
|
{
|
||||||
EXILE_LOG_ERROR("Too many argfilters supplied\n");
|
EXILE_LOG_ERROR("Too many argfilters supplied\n");
|
||||||
|
exile_policy->exile_flags |= EXILE_FLAG_ADD_SYSCALL_POLICY_FAIL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for(size_t i = 0; i < n; i++)
|
for(size_t i = 0; i < n; i++)
|
||||||
@ -939,10 +947,19 @@ int exile_append_path_policies(struct exile_policy *exile_policy, unsigned int p
|
|||||||
path = va_arg(args, char*);
|
path = va_arg(args, char*);
|
||||||
while(path != NULL)
|
while(path != NULL)
|
||||||
{
|
{
|
||||||
|
int fd = open(path, O_PATH);
|
||||||
|
if(fd == -1)
|
||||||
|
{
|
||||||
|
EXILE_LOG_ERROR("Failed to open the specified path: %s\n", strerror(errno));
|
||||||
|
exile_policy->exile_flags |= EXILE_FLAG_ADD_PATH_POLICY_FAIL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
struct exile_path_policy *newpolicy = (struct exile_path_policy *) calloc(1, sizeof(struct exile_path_policy));
|
struct exile_path_policy *newpolicy = (struct exile_path_policy *) calloc(1, sizeof(struct exile_path_policy));
|
||||||
if(newpolicy == NULL)
|
if(newpolicy == NULL)
|
||||||
{
|
{
|
||||||
EXILE_LOG_ERROR("Failed to allocate memory for path policy\n");
|
EXILE_LOG_ERROR("Failed to allocate memory for path policy\n");
|
||||||
|
exile_policy->exile_flags |= EXILE_FLAG_ADD_PATH_POLICY_FAIL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
newpolicy->path = path;
|
newpolicy->path = path;
|
||||||
@ -1763,6 +1780,11 @@ static int enable_no_fs(struct exile_policy *policy)
|
|||||||
*/
|
*/
|
||||||
int exile_enable_policy(struct exile_policy *policy)
|
int exile_enable_policy(struct exile_policy *policy)
|
||||||
{
|
{
|
||||||
|
if((policy->exile_flags & EXILE_FLAG_ADD_PATH_POLICY_FAIL) || (policy->exile_flags & EXILE_FLAG_ADD_SYSCALL_POLICY_FAIL))
|
||||||
|
{
|
||||||
|
EXILE_LOG_ERROR("Error: At least one syscall or path policy was not successfully added!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
if(check_policy_sanity(policy) != 0)
|
if(check_policy_sanity(policy) != 0)
|
||||||
{
|
{
|
||||||
EXILE_LOG_ERROR("Error: Policy sanity check failed. Cannot apply policy!\n");
|
EXILE_LOG_ERROR("Error: Policy sanity check failed. Cannot apply policy!\n");
|
||||||
|
13
test.c
13
test.c
@ -530,6 +530,18 @@ int test_mkpath()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_fail_flags()
|
||||||
|
{
|
||||||
|
struct exile_policy *policy = exile_init_policy();
|
||||||
|
exile_append_path_policy(policy, EXILE_FS_ALLOW_ALL_READ, "/nosuchpathexists");
|
||||||
|
int ret = exile_enable_policy(policy);
|
||||||
|
if(ret == 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed: A path that does not exist should have set the error flag %i\n", ret);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct dispatcher
|
struct dispatcher
|
||||||
{
|
{
|
||||||
@ -554,6 +566,7 @@ struct dispatcher dispatchers[] = {
|
|||||||
{ "no_fs", &test_nofs},
|
{ "no_fs", &test_nofs},
|
||||||
{ "no_new_fds", &test_no_new_fds},
|
{ "no_new_fds", &test_no_new_fds},
|
||||||
{ "mkpath", &test_mkpath},
|
{ "mkpath", &test_mkpath},
|
||||||
|
{ "failflags", &test_fail_flags},
|
||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
Loading…
Reference in New Issue
Block a user