Commit ab7a6fa5 authored by Lukas Braun's avatar Lukas Braun Committed by Simon Ruderich
Browse files

slsm: path_link: prevent removal of inherit flag

Add test.
parent 447fdc9d
......@@ -200,22 +200,34 @@ static int passt_path_link(struct dentry *old_dentry, struct path *new_dir,
/* TODO: is the mountpoint always the same for new_ and old_dentry?
* bindmounts etc. */
struct path target = { new_dir->mnt, old_dentry };
struct slsm_perms would_get;
char *buffer = NULL;
const char *link_name = NULL;
struct slsm_perms perms, would_get;
char *link_buffer = NULL, *target_buffer = NULL;
const char *link_name, *target_name;
int ret;
if (passt_path_common(new_dir, current->cred, SLSM_PERMS_W))
return -EACCES;
link_name = passt_get_path(&link, &buffer);
if (IS_ERR(link_name)) {
kfree(buffer);
return PTR_ERR(link_name);
target_name = passt_get_path(&target, &target_buffer);
if (IS_ERR(target_name)) {
ret = PTR_ERR(target_name);
goto cleanup;
}
perms = slsm_query_perms(target_name, pt->label);
link_name = passt_get_path(&link, &link_buffer);
if (IS_ERR(link_name)) {
ret = PTR_ERR(link_name);
goto cleanup;
}
would_get = slsm_query_perms(link_name, pt->label);
kfree(buffer);
return passt_path_common(&target, current->cred, would_get);
ret = slsm_perms_would_elevate(perms, would_get) ? -EACCES : 0;
cleanup:
kfree(link_buffer);
kfree(target_buffer);
return ret;
}
static int passt_path_symlink(struct path *dir, struct dentry *dentry,
......
......@@ -128,6 +128,14 @@ test_expect_success 'no circumvention via hardlinks' "
ln /tmp/slsm/test-me /tmp/slsm/test-me2 &&
test_must_fail ln /tmp/slsm/test-me /tmp/slsm/test-me3
"
test_expect_success 'no circumvention via hardlinks (inherit)' "
test_when_finished cleanup && setup &&
touch /tmp/slsm/test-me &&
\
rules p=/tmp/slsm/test-me m=5 f=1 '' \
p=/tmp/slsm/test-me2 m=5 &&
test_must_fail ln /tmp/slsm/test-me /tmp/slsm/test-me2
"
test_expect_success 'disallow all access to file' "
test_when_finished cleanup && setup &&
......
......@@ -145,6 +145,20 @@ unsigned slsm_perms_mode_grant(struct slsm_perms perms, struct slsm_perms perms_
return (perms.mode & perms_want.mode) == perms_want.mode;
}
unsigned slsm_perms_would_elevate(struct slsm_perms perms, struct slsm_perms perms_would_get) {
unsigned flags, flags_would_get;
unsigned restrictions = SLSM_FLAG_INHERIT;
if (!slsm_perms_mode_grant(perms, perms_would_get))
return 1;
flags = perms.flags & restrictions;
flags_would_get = perms_would_get.flags & restrictions;
if ((flags & flags_would_get) != flags)
return 1;
return 0;
}
/************************************************************************
......
......@@ -80,4 +80,15 @@ struct slsm_perms slsm_query_perms(const char *path, const char *app);
*/
unsigned slsm_perms_mode_grant(struct slsm_perms perms, struct slsm_perms perms_want);
/**
* slsm_perms_would_elevate - check if the process can elevate its permissions
* if it gets access to @perms_would_get
*
* @perms: perms the process has
* @perms_would_get: perms the process wants to get access to
*
* Returns: 1 if the permissions would be elevated, 0 otherwise
*/
unsigned slsm_perms_would_elevate(struct slsm_perms perms, struct slsm_perms perms_would_get);
#endif /* __SLSM_TREE_H */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment