File: clone.c

package info (click to toggle)
setools 2.0-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 14,112 kB
  • ctags: 10,502
  • sloc: ansic: 76,267; tcl: 27,222; yacc: 2,943; makefile: 993; sh: 504; lex: 244
file content (179 lines) | stat: -rw-r--r-- 6,485 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
 /* Copyright (C) 2001 Tresys Technology, LLC
 * see file 'COPYING' for use and warranty information */

/* 
 * Author: mayerf@tresys.com 
 */

/* apolicy 
 *
 * Functions to resolve clone rules dynamically */
#include "policy.h"
#include "util.h"
#include <stdio.h>
#include <assert.h>


/* Find TE rules that match as a result of clone rules.  For our analysis policy DB,
 * we don't expand the DB to add rules cloned....rather we store the clone rule and
 * then resolve cloned rules when asked for matches (using this function).  The clone
 * rule has some specical cases, and there are some tricky differences between
 * checkpolicy and here.  Some of the interesting cases are:
 *
 * 1. If the rule is RULE_TE_TRANS (type_transition) and the object class is 'process',
 *    checkpolicy does not clone the rule if the 'default' type in the type_transition
 *    rule is equal to either the clone rule's src or tgt types.
 *
 * 2. For all AV rules, checkpolicy does not clone the rule if the AV's rule tgt type is
 *    is equal to either the clone rule's src or tgt types.
 *
 * 3. Since we don't expand our rules to remove attributes (unlike checkpolicy), we have to 
 *    deal with attribute resolution when searching for matches.  However, we have to be 
 *    mindful of the two special cases above.  Since attributes usually match more than
 *    one type, we can't simply throw out a clone if the clone rule's src or tgt types
 *    mactch per case 1 or 2 above.  If the attribute has more than one associated type,
 *    then we would treat it as a "cloned" rule.
 *
 * NOTE: Rules are cloned only if the clone's src type is equal to the rule's src type (i.e.,
 * the clone's type refers to "DOMAINS" which are always represented by the src type.
 */

/* return 1 on match, 0 otherwise */ 
static bool_t attrib_has_single_matching_type(int idx, name_a_t *attrib)
{
	if(attrib->num == 1 && attrib->a[0] == idx)
		return 1;
	else
		return 0;
}


/* return 1 if the special rules didn't prevent a match, 0 otherwise */ 
static bool_t check_clone_specials_av(int src_idx, int tgt_idx, av_item_t *av_rule, policy_t *policy)
{
	ta_item_t *ptr;
	bool_t ans1, ans2;

	/* we go through attribs/types ensuring that they are not just the src and tgt
	 * types (or single attributes for those types).  I.e., we're looking for an idication that a type other 
	 * than just the src and/or idx types are used in the rule's target field. */
	for(ptr = av_rule->tgt_types; ptr != NULL; ptr = ptr->next) {
		if(ptr->type == IDX_TYPE) {
			if(ptr->idx != src_idx && ptr->idx != tgt_idx)
				return 1;
		}
		else {
			ans1 = attrib_has_single_matching_type(src_idx, &(policy->attribs[ptr->idx]));
			ans2 = attrib_has_single_matching_type(tgt_idx, &(policy->attribs[ptr->idx]));
			if(!ans1 && !ans2)
				return 1;
		}		
	}
	
	return 0; /* i.e., the AV rule's target field relates ONLY to the clone's src and/or tgt types */
}

/* return 1 if the special rules didn't prevent a match, 0 otherwise */ 
/* for TT rules, all we care about is the default type.  Since clone's src and tgt, and TT's default
 * are all ONLY types, we don't have to worry about resolving attributes! */
static bool_t check_clone_specials_tt(int src_idx, int tgt_idx, tt_item_t *tt_rule, policy_t *policy)
{
	bool_t ans;
	/* only type transition rules */
	if(tt_rule->type != RULE_TE_TRANS)
		return 1;
	
	/* only if they relate to process object class */
	ans = is_name_in_list("process", tt_rule->classes, policy);
	if(!ans)
		return 1;
	
	if(tt_rule->dflt_type.idx == src_idx || tt_rule->dflt_type.idx == tgt_idx)
		return 0;
	
	return 1;
}

/* FIX: BUG....need to address '~' and '*', and test the logic here more...clones are tricky
 * when we aren't expanding rules! */
int match_cloned_rules(int  idx,			
                             bool_t include_audit,
                             rules_bool_t *rules_b,
                             policy_t *policy
                             )
{
	int i, cnt;
	int ans;
	cln_item_t *ptr;
	if(rules_b == NULL || policy == NULL || idx >= policy->num_types)
		return -1;
		
	for(ptr = policy->clones; ptr != NULL; ptr = ptr->next) {
		/* A clone rule copies the rules for the src type to the tgt type, except 
		 * for the special cases above; so we check if the clone rule's tgt matches our idx */
		if(idx == ptr->tgt) {
			/* access AV rules */
			for(i = 0; i < policy->num_av_access; i++) {
				/* if the rule is already recorded as a match, don't waste time checking again */
				if(rules_b->access[i])
					break;
				/* Since the clone's tgt relates to our idx, we have to see if the clone's
				 * src is in the src type/attrib list for all rules, and if so and if special
				 * checks don't say otherwise, we record that rule as being "cloned" for the 
				 * provided type 'idx' */
				ans = does_av_rule_use_type(ptr->src, IDX_TYPE, SRC_LIST, 1, &(policy->av_access[i]),
						&cnt, policy);
				if (ans == -1)
					return -1;
				else if(ans) {
					ans = check_clone_specials_av(ptr->src, ptr->tgt, &(policy->av_access[i]), policy);
					if(ans) {
						rules_b->access[i] = 1;
						(rules_b->ac_cnt)++;
					}
				}
			}
			/* TT rules */
			for(i = 0; i < policy->num_te_trans; i++) {
				if(rules_b->ttrules[i])
					break;
				ans = does_tt_rule_use_type(ptr->src, IDX_TYPE, SRC_LIST, 1,
						&(policy->te_trans[i]), &cnt, policy);
				if (ans == -1)
					return -1;
				else if(ans) {
					ans = check_clone_specials_tt(ptr->src, ptr->tgt, &(policy->te_trans[i]), policy);
					if(ans) {
						rules_b->ttrules[i] = 1;
						(rules_b->tt_cnt)++;
					}
				}
			}
			/* audit AV rules */
			if(include_audit) {
				for(i = 0; i < policy->num_av_audit; i++) {
					/* if the rule is already recorded as a match, don't waste time checking again */
					if(rules_b->audit[i])
						break;
					/* Since the clone's tgt relates to our idx, we have to see if the clone's
					 * src is in the src type/attrib list for all rules, and if so and if special
					 * checks don't say otherwise, we record that rule as being "cloned" for the 
					 * provided type 'idx' */
					ans = does_av_rule_use_type(ptr->src, IDX_TYPE, SRC_LIST, 1, &(policy->av_audit[i]),
							&cnt, policy);
					if (ans == -1)
						return -1;
					else if (ans) {
						ans = check_clone_specials_av(ptr->src, ptr->tgt, &(policy->av_audit[i]), policy);
						if(ans) {
							rules_b->audit[i] = 1;
							(rules_b->au_cnt)++;
						}
					}
				}				
			}		
		}
	}
	
	return 0;
}