Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow non-parent functions to be cast #128

Merged
merged 10 commits into from
Mar 17, 2023
Merged
61 changes: 61 additions & 0 deletions data/error_policies/call_casting.cas
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
virtual resource bar {
fn read(domain source) {
allow(source, this, file, read);
}
}

virtual resource zap {
fn write(domain source) {
allow(source, this, file, write);
}
}

resource foo inherits bar {
fn read(domain source) {
allow(source, this, dir, read);
}
}

domain dom {
foo<qqq>.read(this); // Function does not exist
foo<zap>.read(this); // Function does not exist
foo<bar>.write(this); // Function does not exist
}

domain asd {
asd<boo>.read_boo_tmp(this); // Function is not castable
asd<boo>.read_boo_tmp_again(this); // Function is not castable
asd<boo>.read_boo_tmp_more(this); // Function is not castable
asd<boo>.some_function(foo);
}

virtual resource tmp {
@associated_call
fn associated_call_from_tmp(domain source) {
allow(source, tmp, file, [read]);
}
}

@associate([tmp])
domain boo {
// Creates new resources boo.tmp and implicitly calls
// boo.tmp.associated_call_from_tmp(boo)
//
// boo.tmp inherits tmp

fn read_boo_tmp(domain source) {
allow(source, boo.tmp, file, [read]);
}

fn read_boo_tmp_again(domain source) {
boo.tmp.associated_call_from_tmp(source);
}

fn read_boo_tmp_more(domain source) {
this.some_function(this.tmp);
}

fn some_function(resource res) {
allow(this, res, file, read);
}
}
20 changes: 20 additions & 0 deletions data/error_policies/functions_no_term.cas
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
resource my_file {
fn read(domain source) {
allow(source, this, file, [ read open getattr ]);
other_read(source);
}

fn other_read(domain source) {
allow(source, this, file, [ read open getattr ]);
third_read(source);
}

fn third_read(domain source) {
allow(source, this, file, [ read open getattr ]);
read(source);
}
}

domain my_domain {
my_file.read(this); // TODO: support 'this' as default argument
}
29 changes: 29 additions & 0 deletions data/error_policies/functions_recursion.cas
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
resource my_file {
fn read(domain source) {
allow(source, this, file, [ read open getattr ]);
other_read(source);
}

fn other_read(domain source) {
allow(source, this, file, [ read open getattr ]);
third_read(source);
}

fn third_read(domain source) {
allow(source, this, file, [ read open getattr ]);
read(source);
}

fn term_read(domain source) {
if (true) {
allow(source, this, file, [ read open getattr ]);
}
optional {
allow(source, this, dir, [ search ]);
}
}
}

domain my_domain {
my_file.read(this); // TODO: support 'this' as default argument
}
24 changes: 0 additions & 24 deletions data/error_policies/parent_call.cas

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,13 @@
(typeattribute resource)
(typeattribute abc)
(typeattributeset resource (abc))
(type asd)
(roletype system_r asd)
(typeattributeset domain (asd))
(typeattribute bar)
(typeattributeset resource (bar))
(typeattribute boo)
(typeattributeset domain (boo))
(type dom)
(roletype system_r dom)
(typeattributeset domain (dom))
Expand All @@ -139,25 +144,47 @@
(type security_sid)
(roletype object_r security_sid)
(typeattributeset resource (security_sid))
(typeattribute tmp)
(typeattributeset resource (tmp))
(type unlabeled_sid)
(roletype object_r unlabeled_sid)
(typeattributeset resource (unlabeled_sid))
(typeattribute boo-tmp)
(typeattributeset tmp (boo-tmp))
(typeattributeset resource (boo-tmp))
(type foo)
(roletype object_r foo)
(typeattributeset bar (foo))
(typeattributeset resource (foo))
(type jkl)
(roletype system_r jkl)
(typeattributeset boo (jkl))
(typeattributeset domain (jkl))
(type xyz)
(roletype object_r xyz)
(typeattributeset abc (xyz))
(typeattributeset resource (xyz))
(type jkl-tmp)
(roletype object_r jkl-tmp)
(typeattributeset boo-tmp (jkl-tmp))
(typeattributeset resource (jkl-tmp))
(macro abc-read ((type this) (type source)) (allow source this (file (read))))
(macro bar-foobar ((type this) (type source)) (allow source this (dir (search))))
(macro bar-read ((type this) (type source)) (allow source this (file (read))))
(macro boo-read_boo_tmp ((type this) (type source)) (allow source boo-tmp (file (read))))
(macro boo-tmp-associated_call_from_tmp ((type this) (type source)) (allow source tmp (file (read))))
(macro foo-foobar ((type this) (type source)) (allow source this (dir (search))))
(macro foo-read ((type this) (type source)) (allow source this (dir (read))))
(macro jkl-tmp-associated_call_from_tmp ((type this) (type source)) (allow source tmp (file (read))))
(macro tmp-associated_call_from_tmp ((type this) (type source)) (allow source tmp (file (read))))
(macro xyz-read ((type this) (type source)) (call abc-read (abc source)))
(call abc-read (asd asd))
(call abc-read (foo asd))
(call bar-foobar (foo dom))
(call bar-read (foo dom))
(call boo-read_boo_tmp (jkl jkl))
(call boo-tmp-associated_call_from_tmp (boo-tmp boo))
(call jkl-tmp-associated_call_from_tmp (jkl-tmp jkl))
(sid kernel)
(sidcontext kernel (system_u system_r kernel_sid ((s0) (s0))))
(sid security)
Expand Down
33 changes: 27 additions & 6 deletions data/policies/parent_call.cas → data/policies/call_casting.cas
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,30 @@ resource xyz inherits abc {
}
}

// TODOs once we add the ability to cast to
// non-inherited things
//
//domain asd {
// asd<abc>.read(this);
//}
domain asd {
asd<abc>.read(this);
foo<abc>.read(this);
}

domain jkl inherits boo {
jkl<boo>.read_boo_tmp(this);
}

virtual resource tmp {
@associated_call
fn associated_call_from_tmp(domain source) {
allow(source, tmp, file, [read]);
}
}

@associate([tmp])
virtual domain boo {
// Creates new resources boo.tmp and implicitly calls
// boo.tmp.associated_call_from_tmp(boo)
//
// boo.tmp inherits tmp

fn read_boo_tmp(domain source) {
allow(source, boo.tmp, file, [read]);
matt-sheets marked this conversation as resolved.
Show resolved Hide resolved
}
}
27 changes: 27 additions & 0 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,33 @@ impl Statement {
}
}

// The function will take a vector of statements and reduce them down
// to only their function calls.
dburgener marked this conversation as resolved.
Show resolved Hide resolved
// Note: This will expand out all possible function calls regardless
// of boolean & optional block state.
pub fn get_all_func_calls(statements: Vec<Statement>) -> Vec<FuncCall> {
let mut ret_vec: Vec<FuncCall> = Vec::new();
for call in statements {
match call {
Statement::Call(call) => {
ret_vec.push(*call);
}
Statement::LetBinding(_) => {
continue;
}
Statement::IfBlock(call) => {
ret_vec.extend(get_all_func_calls(call.if_statements));
ret_vec.extend(get_all_func_calls(call.else_statements));
}
Statement::OptionalBlock(call) => {
ret_vec.extend(get_all_func_calls(call.contents));
}
}
}

ret_vec
}

pub enum BuiltIns {
AvRule,
FileContext,
Expand Down
23 changes: 22 additions & 1 deletion src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use crate::error::{
add_or_create_compile_error, CascadeErrors, CompileError, ErrorItem, InternalError,
};
use crate::functions::{
determine_castable, initialize_castable, initialize_terminated, search_for_recursion,
ArgForValidation, FSContextType, FileSystemContextRule, FunctionArgument, FunctionClass,
FunctionInfo, FunctionMap, ValidatedCall, ValidatedStatement,
};
Expand Down Expand Up @@ -488,6 +489,24 @@ pub fn validate_rules(statements: &BTreeSet<ValidatedStatement>) -> Result<(), C
errors.into_result(())
}

pub fn prevalidate_functions(
dburgener marked this conversation as resolved.
Show resolved Hide resolved
functions: &mut FunctionMap,
types: &TypeMap,
) -> Result<(), CascadeErrors> {
initialize_castable(functions, types);
// We initialize to 1 just to let the loop start once
let mut num_changed: u64 = 1;
while num_changed > 0 {
num_changed = determine_castable(functions, types);
}

let (mut terminated_functions, mut nonterm_functions) = initialize_terminated(functions);

search_for_recursion(&mut terminated_functions, &mut nonterm_functions, functions)?;

Ok(())
}

// Mutate hash map to set the validated body
pub fn validate_functions<'a>(
mut functions: FunctionMap<'a>,
Expand Down Expand Up @@ -953,7 +972,9 @@ pub fn get_reduced_infos(
new_type_map.set_aliases(new_t_aliases);

// Get the function infos
let new_func_map = get_funcs(policies, &new_type_map)?;
let mut new_func_map = get_funcs(policies, &new_type_map)?;

prevalidate_functions(&mut new_func_map, &new_type_map)?;

// Validate functions, including deriving functions from annotations
let new_func_map_copy = new_func_map.clone(); // In order to read function info while mutating
Expand Down
Loading