Skip to content

Commit f9ecf1f

Browse files
authored
Allow non-parent functions to be cast (#128)
* Allow non-parent functions to be cast Previously one could only cast a function if it was from an inherited type. Now you can cast a function as long as the function does not reference any associated types. * add recursion validation
1 parent dac3531 commit f9ecf1f

File tree

11 files changed

+438
-54
lines changed

11 files changed

+438
-54
lines changed

data/error_policies/call_casting.cas

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
virtual resource bar {
2+
fn read(domain source) {
3+
allow(source, this, file, read);
4+
}
5+
}
6+
7+
virtual resource zap {
8+
fn write(domain source) {
9+
allow(source, this, file, write);
10+
}
11+
}
12+
13+
resource foo inherits bar {
14+
fn read(domain source) {
15+
allow(source, this, dir, read);
16+
}
17+
}
18+
19+
domain dom {
20+
foo<qqq>.read(this); // Function does not exist
21+
foo<zap>.read(this); // Function does not exist
22+
foo<bar>.write(this); // Function does not exist
23+
}
24+
25+
domain asd {
26+
asd<boo>.read_boo_tmp(this); // Function is not castable
27+
asd<boo>.read_boo_tmp_again(this); // Function is not castable
28+
asd<boo>.read_boo_tmp_more(this); // Function is not castable
29+
asd<boo>.some_function(foo);
30+
}
31+
32+
virtual resource tmp {
33+
@associated_call
34+
fn associated_call_from_tmp(domain source) {
35+
allow(source, tmp, file, [read]);
36+
}
37+
}
38+
39+
@associate([tmp])
40+
domain boo {
41+
// Creates new resources boo.tmp and implicitly calls
42+
// boo.tmp.associated_call_from_tmp(boo)
43+
//
44+
// boo.tmp inherits tmp
45+
46+
fn read_boo_tmp(domain source) {
47+
allow(source, boo.tmp, file, [read]);
48+
}
49+
50+
fn read_boo_tmp_again(domain source) {
51+
boo.tmp.associated_call_from_tmp(source);
52+
}
53+
54+
fn read_boo_tmp_more(domain source) {
55+
this.some_function(this.tmp);
56+
}
57+
58+
fn some_function(resource res) {
59+
allow(this, res, file, read);
60+
}
61+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
resource my_file {
2+
fn read(domain source) {
3+
allow(source, this, file, [ read open getattr ]);
4+
other_read(source);
5+
}
6+
7+
fn other_read(domain source) {
8+
allow(source, this, file, [ read open getattr ]);
9+
third_read(source);
10+
}
11+
12+
fn third_read(domain source) {
13+
allow(source, this, file, [ read open getattr ]);
14+
read(source);
15+
}
16+
}
17+
18+
domain my_domain {
19+
my_file.read(this); // TODO: support 'this' as default argument
20+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
resource my_file {
2+
fn read(domain source) {
3+
allow(source, this, file, [ read open getattr ]);
4+
other_read(source);
5+
}
6+
7+
fn other_read(domain source) {
8+
allow(source, this, file, [ read open getattr ]);
9+
third_read(source);
10+
}
11+
12+
fn third_read(domain source) {
13+
allow(source, this, file, [ read open getattr ]);
14+
read(source);
15+
}
16+
17+
fn term_read(domain source) {
18+
if (true) {
19+
allow(source, this, file, [ read open getattr ]);
20+
}
21+
optional {
22+
allow(source, this, dir, [ search ]);
23+
}
24+
}
25+
}
26+
27+
domain my_domain {
28+
my_file.read(this); // TODO: support 'this' as default argument
29+
}

data/error_policies/parent_call.cas

Lines changed: 0 additions & 24 deletions
This file was deleted.

data/expected_cil/parent_call.cil renamed to data/expected_cil/call_casting.cil

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,13 @@
128128
(typeattribute resource)
129129
(typeattribute abc)
130130
(typeattributeset resource (abc))
131+
(type asd)
132+
(roletype system_r asd)
133+
(typeattributeset domain (asd))
131134
(typeattribute bar)
132135
(typeattributeset resource (bar))
136+
(typeattribute boo)
137+
(typeattributeset domain (boo))
133138
(type dom)
134139
(roletype system_r dom)
135140
(typeattributeset domain (dom))
@@ -139,25 +144,47 @@
139144
(type security_sid)
140145
(roletype object_r security_sid)
141146
(typeattributeset resource (security_sid))
147+
(typeattribute tmp)
148+
(typeattributeset resource (tmp))
142149
(type unlabeled_sid)
143150
(roletype object_r unlabeled_sid)
144151
(typeattributeset resource (unlabeled_sid))
152+
(typeattribute boo-tmp)
153+
(typeattributeset tmp (boo-tmp))
154+
(typeattributeset resource (boo-tmp))
145155
(type foo)
146156
(roletype object_r foo)
147157
(typeattributeset bar (foo))
148158
(typeattributeset resource (foo))
159+
(type jkl)
160+
(roletype system_r jkl)
161+
(typeattributeset boo (jkl))
162+
(typeattributeset domain (jkl))
149163
(type xyz)
150164
(roletype object_r xyz)
151165
(typeattributeset abc (xyz))
152166
(typeattributeset resource (xyz))
167+
(type jkl-tmp)
168+
(roletype object_r jkl-tmp)
169+
(typeattributeset boo-tmp (jkl-tmp))
170+
(typeattributeset resource (jkl-tmp))
153171
(macro abc-read ((type this) (type source)) (allow source this (file (read))))
154172
(macro bar-foobar ((type this) (type source)) (allow source this (dir (search))))
155173
(macro bar-read ((type this) (type source)) (allow source this (file (read))))
174+
(macro boo-read_boo_tmp ((type this) (type source)) (allow source boo-tmp (file (read))))
175+
(macro boo-tmp-associated_call_from_tmp ((type this) (type source)) (allow source tmp (file (read))))
156176
(macro foo-foobar ((type this) (type source)) (allow source this (dir (search))))
157177
(macro foo-read ((type this) (type source)) (allow source this (dir (read))))
178+
(macro jkl-tmp-associated_call_from_tmp ((type this) (type source)) (allow source tmp (file (read))))
179+
(macro tmp-associated_call_from_tmp ((type this) (type source)) (allow source tmp (file (read))))
158180
(macro xyz-read ((type this) (type source)) (call abc-read (abc source)))
181+
(call abc-read (asd asd))
182+
(call abc-read (foo asd))
159183
(call bar-foobar (foo dom))
160184
(call bar-read (foo dom))
185+
(call boo-read_boo_tmp (jkl jkl))
186+
(call boo-tmp-associated_call_from_tmp (boo-tmp boo))
187+
(call jkl-tmp-associated_call_from_tmp (jkl-tmp jkl))
161188
(sid kernel)
162189
(sidcontext kernel (system_u system_r kernel_sid ((s0) (s0))))
163190
(sid security)

data/policies/parent_call.cas renamed to data/policies/call_casting.cas

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,30 @@ resource xyz inherits abc {
3333
}
3434
}
3535

36-
// TODOs once we add the ability to cast to
37-
// non-inherited things
38-
//
39-
//domain asd {
40-
// asd<abc>.read(this);
41-
//}
36+
domain asd {
37+
asd<abc>.read(this);
38+
foo<abc>.read(this);
39+
}
40+
41+
domain jkl inherits boo {
42+
jkl<boo>.read_boo_tmp(this);
43+
}
44+
45+
virtual resource tmp {
46+
@associated_call
47+
fn associated_call_from_tmp(domain source) {
48+
allow(source, tmp, file, [read]);
49+
}
50+
}
51+
52+
@associate([tmp])
53+
virtual domain boo {
54+
// Creates new resources boo.tmp and implicitly calls
55+
// boo.tmp.associated_call_from_tmp(boo)
56+
//
57+
// boo.tmp inherits tmp
58+
59+
fn read_boo_tmp(domain source) {
60+
allow(source, boo.tmp, file, [read]);
61+
}
62+
}

src/ast.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,33 @@ impl Statement {
455455
}
456456
}
457457

458+
// The function will take a vector of statements and reduce them down
459+
// to only their function calls.
460+
// Note: This will expand out all possible function calls regardless
461+
// of boolean & optional block state.
462+
pub fn get_all_func_calls(statements: Vec<Statement>) -> Vec<FuncCall> {
463+
let mut ret_vec: Vec<FuncCall> = Vec::new();
464+
for call in statements {
465+
match call {
466+
Statement::Call(call) => {
467+
ret_vec.push(*call);
468+
}
469+
Statement::LetBinding(_) => {
470+
continue;
471+
}
472+
Statement::IfBlock(call) => {
473+
ret_vec.extend(get_all_func_calls(call.if_statements));
474+
ret_vec.extend(get_all_func_calls(call.else_statements));
475+
}
476+
Statement::OptionalBlock(call) => {
477+
ret_vec.extend(get_all_func_calls(call.contents));
478+
}
479+
}
480+
}
481+
482+
ret_vec
483+
}
484+
458485
pub enum BuiltIns {
459486
AvRule,
460487
FileContext,

src/compile.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::error::{
1717
add_or_create_compile_error, CascadeErrors, CompileError, ErrorItem, InternalError,
1818
};
1919
use crate::functions::{
20+
determine_castable, initialize_castable, initialize_terminated, search_for_recursion,
2021
ArgForValidation, FSContextType, FileSystemContextRule, FunctionArgument, FunctionClass,
2122
FunctionInfo, FunctionMap, ValidatedCall, ValidatedStatement,
2223
};
@@ -488,6 +489,24 @@ pub fn validate_rules(statements: &BTreeSet<ValidatedStatement>) -> Result<(), C
488489
errors.into_result(())
489490
}
490491

492+
pub fn prevalidate_functions(
493+
functions: &mut FunctionMap,
494+
types: &TypeMap,
495+
) -> Result<(), CascadeErrors> {
496+
initialize_castable(functions, types);
497+
// We initialize to 1 just to let the loop start once
498+
let mut num_changed: u64 = 1;
499+
while num_changed > 0 {
500+
num_changed = determine_castable(functions, types);
501+
}
502+
503+
let (mut terminated_functions, mut nonterm_functions) = initialize_terminated(functions);
504+
505+
search_for_recursion(&mut terminated_functions, &mut nonterm_functions, functions)?;
506+
507+
Ok(())
508+
}
509+
491510
// Mutate hash map to set the validated body
492511
pub fn validate_functions<'a>(
493512
mut functions: FunctionMap<'a>,
@@ -953,7 +972,9 @@ pub fn get_reduced_infos(
953972
new_type_map.set_aliases(new_t_aliases);
954973

955974
// Get the function infos
956-
let new_func_map = get_funcs(policies, &new_type_map)?;
975+
let mut new_func_map = get_funcs(policies, &new_type_map)?;
976+
977+
prevalidate_functions(&mut new_func_map, &new_type_map)?;
957978

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

0 commit comments

Comments
 (0)