* [RFC & PATCH] inherited type definition.
@ 2005-03-13 16:36 KaiGai Kohei
2005-03-14 13:17 ` KaiGai Kohei
` (2 more replies)
0 siblings, 3 replies; 58+ messages in thread
From: KaiGai Kohei @ 2005-03-13 16:36 UTC (permalink / raw)
To: SELinux Mail List; +Cc: kaigai
[-- Attachment #1: Type: text/plain, Size: 5276 bytes --]
Hello,
This attached patch provids a new syntax extension to checkpolicy.
This makes it possible to describe a definition of type which inherit
access vectors of parent's types/attributes.
Syntax:
TYPE <type> [ALIAS <aliases>] EXTENDS <type/attr>, <type/attr>, ... ;
The basical idea is like attribute, but 'EXTENDS' has those differences as follows:
- It can inherit other types, not only attribute.
- It can describe multi-layer inheritance tree of type.
Currently, when we try to define a type like another type, we must describe a new
type from a scratch for tiny difference. For example, if we want a new type
'ext_user_t' which is permitted all access vectors for user_t and a tiny additional
access vectors, we must describe all of the user_t's access vectors and some of
original allow-statements.
When you use EXTENDS extension, only what you describe are a type definition
with EXTENDS statement and some original allow-statements.
[Simple Example]
type subject_t;
type parent_t;
type child_t extends parent_t;
type grandchild_t extends child_t;
type stranger_t;
In this case, there are five types for explanation.
- "allow subject_t child_t:XXX XXX;" means "allow subject_t {child_t grandchild_t}:XXX XXX".
- "allow parent_t child_t:XXX XXX;" means "allow {parent_t child_t grandchild_t} {child_t grandchild_t}:XXX XXX"
- "allow subject_t ~parent_t:XXX XXX" means "allow subject_t stranger_t:XXX XXX".
child_t and grandchild_t are not included in ~parent_t, because its ancestor is parent_t.
- "allow child_t self:XXX XXX" means "allow child_t child_t:XXX XXX",
"allow child_t grandchild_t:XXX XXX" and "allow grandchild_t grandchild_t:XXX XXX".
An access vector granted to parent-type is inherited to child and grandchild.
We must pay attention to '~' and 'self'.
When we use '~', that means the reverse of the type and its children.
When we use 'self', that means the type and its children.
Thanks, any comments please.
# This is a personal work, but would you Cc: 'kaigai@ak.jp.nec.com' for useful ?
--------------------------------------------------------------------
When we don't use EXTENDS statement, checkpolicy works compatibly.
I tried to test checkpolicy-1.20 with EXTENDS patch by Tresys's sediff and policy-1.20.
Test 1: compatibility of the checkpolicy
[kaigai@ayu ~]$ sediff polbin.org polbin.std
Difference between policy 1 and policy 2:
p1 (binary, ver: 18): polbin.org ... generated by standard checkpolicy
p2 (binary, ver: 18): polbin.std ... generated by extended checkpolicy
Types (0 Added, 0 Removed, 0 Changed)
Added Types: 0
Removed Types: 0
Changed Types: 0
Roles (0 Added, 0 Removed, 0 Changed)
Added Roles: 0
Removed Roles: 0
Changed Roles: 0
Users (0 Added, 0 Removed, 0 Changed)
Added Users: 0
Removed Users: 0
Changed Users: 0
Booleans (0 Added, 0 Removed, 0 Changed)
Added Booleans: 0
Removed Booleans: 0
Changed Booleans: 0
Classes (0 Added, 0 Removed, 0 Changed)
Added Classes: 0
Removed Classes: 0
Changed Classes: 0
Permissions (0 Added, 0 Removed)
Added Permissions: 0
Removed Permissions: 0
Common Permissions (0 Added, 0 Removed, 0 Changed)
Added Common Permissions: 0
Removed Common Permissions: 0
Changed Common Permissions: 0
Conditionals are not currently supported.
Role Allows (0 Added, 0 Removed, 0 Changed)
Added Role Allows: 0
Removed Role Allows: 0
Changed Role Allows: 0
TE Rules (0 Added, 0 Removed, 0 Changed)
Added TE Rules 0:
Removed TE Rules 0:
Changed TE Rules 0:
Total Differences:
Classes & Permissions 0
Types 0
Attributes 0
Roles 0
Users 0
Booleans 0
Rbac 0
TE Rules 0
--------------------------------------------------------------------------
Test 2: The advantage of EXTENDS statement.
I added a line 'type user_ext_t extends user_t;' into policy.conf.
[kaigai@ayu ~]$ sediff polbin.std polbin.ext
Difference between policy 1 and policy 2:
p1 (binary, ver: 18): polbin.std ... original policy-1.20
p2 (binary, ver: 18): polbin.ext ... I added a type definition.
Types (1 Added, 0 Removed, 0 Changed)
Added Types: 1
+ user_ext_t
Removed Types: 0
Changed Types: 0
Roles (0 Added, 0 Removed, 1 Changed)
Added Roles: 0
Removed Roles: 0
Changed Roles: 1
* user_r (1 Added Types)
+ user_ext_t
Users (0 Added, 0 Removed, 0 Changed)
:
<Omitted>
:
TE Rules (1766 Added, 0 Removed, 0 Changed)
Added TE Rules 1766:
+ allow load_policy_t user_ext_t : fd { use };
:
<Omitted>
:
+ allow ifconfig_t user_ext_t : fd { use };
Removed TE Rules 0:
Changed TE Rules 0:
Total Differences:
Classes & Permissions 0
Types 1
Attributes 0
Roles 1
Users 0
Booleans 0
Rbac 0
TE Rules 1766
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
[-- Attachment #2: checkpolicy-1.20-type_extends.patch --]
[-- Type: text/plain, Size: 12933 bytes --]
--- checkpolicy-1.20/policy_scan.l 2004-12-13 16:29:49.000000000 -0500
+++ checkpolicy-1.20.extends/policy_scan.l 2005-03-12 20:43:13.000000000 -0500
@@ -75,8 +75,10 @@
ELSE |
else { return(ELSE); }
ALIAS |
alias { return(ALIAS); }
+EXTENDS |
+extends { return(EXTENDS); }
ATTRIBUTE |
attribute { return(ATTRIBUTE); }
TYPE_TRANSITION |
type_transition { return(TYPE_TRANSITION); }
--- checkpolicy-1.20/checkpolicy.h 2004-08-11 09:38:55.000000000 -0400
+++ checkpolicy-1.20.extends/checkpolicy.h 2005-03-13 22:32:07.000000000 -0500
@@ -15,6 +15,17 @@
te_assert_t *te_assertions;
extern unsigned int policyvers;
+/* type was not indexed in policydb,
+ but it's necessary for extends support. */
+extern type_datum_t **type_val_to_struct;
+extern int num_type_val_to_struct;
+extern void get_child_types(ebitmap_t *set, type_datum_t *t, int depth);
+
+static inline type_datum_t *get_type(int typeval) {
+ if (!type_val_to_struct || typeval<1 || typeval>num_type_val_to_struct)
+ return NULL;
+ return type_val_to_struct[typeval-1];
+}
#endif
--- checkpolicy-1.20/checkpolicy.c 2004-08-11 10:03:19.000000000 -0400
+++ checkpolicy-1.20.extends/checkpolicy.c 2005-03-14 00:48:45.000000000 -0500
@@ -336,8 +336,10 @@
}
void check_assertions(void)
{
+ ebitmap_t temp;
+ type_datum_t *typedatum;
te_assert_t *a, *tmp;
unsigned int i, j;
a = te_assertions;
@@ -345,9 +347,21 @@
for (i = ebitmap_startbit(&a->stypes); i < ebitmap_length(&a->stypes); i++) {
if (!ebitmap_get_bit(&a->stypes, i))
continue;
if (a->self) {
- check_assertion_helper(i, i, &a->tclasses, a->avp, a->line);
+ typedatum = type_val_to_struct[i];
+ if (!typedatum) {
+ fprintf(stderr, "BUG: check_assetion for undefined type.\n");
+ exit(1);
+ }
+ ebitmap_init(&temp);
+ get_child_types(&temp, typedatum, 0);
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if (!ebitmap_get_bit(&temp, j))
+ continue;
+ check_assertion_helper(i, j, &a->tclasses, a->avp, a->line);
+ }
+ ebitmap_destroy(&temp);
}
for (j = ebitmap_startbit(&a->ttypes); j < ebitmap_length(&a->ttypes); j++) {
if (!ebitmap_get_bit(&a->ttypes, j))
continue;
@@ -434,8 +448,43 @@
evaluate_conds(policydbp);
return 0;
}
+type_datum_t **type_val_to_struct = NULL;
+int num_type_val_to_struct = -1;
+
+static int type_val_to_struct_helper(hashtab_key_t k, hashtab_datum_t d, void *args)
+{
+ type_datum_t *t = (type_datum_t *)d;
+ if (!t->isattr && t->primary)
+ type_val_to_struct[t->value-1] = t;
+ return 0; /* always success */
+}
+
+void get_child_types(ebitmap_t *set, type_datum_t *td, int depth)
+{
+ type_datum_t *child;
+ int i;
+
+ if (td->isattr && depth>0) {
+ fprintf(stderr, "BUG: an attribute must not inherit anyone.\n");
+ exit(1);
+ }
+
+ if (!td->isattr && !td->primary)
+ td = get_type(td->value);
+
+ if (!td->isattr)
+ ebitmap_set_bit(set, td->value - 1, 1);
+
+ for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+ if (ebitmap_get_bit(&td->types, i)) {
+ child = type_val_to_struct[i];
+ get_child_types(set, child, depth + 1);
+ }
+ }
+}
+
int main(int argc, char **argv)
{
security_class_t tclass;
security_id_t ssid, tsid, *sids;
@@ -448,9 +497,9 @@
unsigned int protocol, port;
unsigned int binary = 0, debug = 0;
struct val_to_name v;
int ret, ch, fd;
- unsigned int nel;
+ unsigned int nel, len;
struct stat sb;
void *map;
FILE *outfp = NULL;
char *name;
@@ -568,8 +617,20 @@
if (yyparse() || policydb_errors) {
fprintf(stderr, "%s: error(s) encountered while parsing configuration\n", argv[0]);
exit(1);
}
+
+ /* construction of type_val_to_struct */
+ num_type_val_to_struct = policydbp->p_types.nprim;
+ len = sizeof(type_datum_t *) * num_type_val_to_struct;
+ type_val_to_struct = (type_datum_t **)malloc(len);
+ if (!type_val_to_struct) {
+ fprintf(stderr, "type_val_to_struct: out of memory\n");
+ exit(1);
+ }
+ memset(type_val_to_struct, 0, len);
+ hashtab_map(policydbp->p_types.table, type_val_to_struct_helper, NULL);
+
rewind(yyin);
policydb_lineno = 1;
source_file[0] = '\0';
source_lineno = 1;
--- checkpolicy-1.20/policy_parse.y 2004-12-13 16:29:49.000000000 -0500
+++ checkpolicy-1.20.extends/policy_parse.y 2005-03-14 00:49:23.000000000 -0500
@@ -12,8 +12,13 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2.
*/
+/* Updated: KaiGai Kohei, <kaigai@kaigai.gr.jp>
+ * Added inherited type extensions. (2005/03/13)
+ */
+
+
/* FLASK */
%{
#include <sys/types.h>
@@ -68,9 +73,9 @@
static int define_av_base(void);
static int define_attrib(void);
static int define_typealias(void);
static int define_typeattribute(void);
-static int define_type(int alias);
+static int define_type(int alias, int extends);
static int define_compute_type(int which);
static int define_te_avtab(int which);
static int define_role_types(void);
static role_datum_t *merge_roles_dom(role_datum_t *r1,role_datum_t *r2);
@@ -125,8 +130,9 @@
%token TYPEATTRIBUTE
%token TYPE
%token TYPES
%token ALIAS
+%token EXTENDS
%token ATTRIBUTE
%token BOOL
%token IF
%token ELSE
@@ -298,11 +304,15 @@
attribute_def : ATTRIBUTE identifier ';'
{ if (define_attrib()) return -1;}
;
type_def : TYPE identifier alias_def opt_attr_list ';'
- {if (define_type(1)) return -1;}
+ {if (define_type(1, 0)) return -1;}
| TYPE identifier opt_attr_list ';'
- {if (define_type(0)) return -1;}
+ {if (define_type(0, 0)) return -1;}
+ | TYPE identifier alias_def opt_extends_list ';'
+ {if (define_type(1, 1)) return -1;}
+ | TYPE identifier opt_extends_list ';'
+ {if (define_type(0, 1)) return -1;}
;
typealias_def : TYPEALIAS identifier alias_def ';'
{if (define_typealias()) return -1;}
;
@@ -311,8 +321,10 @@
;
opt_attr_list : ',' id_comma_list
|
;
+opt_extends_list : EXTENDS id_comma_list
+ ;
bool_def : BOOL identifier bool_val ';'
{if (define_bool()) return -1;}
;
bool_val : CTRUE
@@ -1676,15 +1688,13 @@
if (ret == HASHTAB_PRESENT) {
sprintf(errormsg, "name conflict for type alias %s", id);
yyerror(errormsg);
- free(aliasdatum);
free(id);
return -1;
}
if (ret == HASHTAB_OVERFLOW) {
yyerror("hash table overflow");
- free(aliasdatum);
free(id);
return -1;
}
}
@@ -1770,12 +1780,12 @@
return 0;
}
-static int define_type(int alias)
+static int define_type(int alias, int extends)
{
char *id;
- type_datum_t *datum, *aliasdatum, *attr;
+ type_datum_t *datum, *aliasdatum, *inherit;
int ret, newattr = 0;
if (pass == 2) {
@@ -1837,15 +1847,13 @@
if (ret == HASHTAB_PRESENT) {
sprintf(errormsg, "name conflict for type alias %s", id);
yyerror(errormsg);
- free(aliasdatum);
free(id);
return -1;
}
if (ret == HASHTAB_OVERFLOW) {
yyerror("hash table overflow");
- free(aliasdatum);
free(id);
return -1;
}
}
@@ -1856,11 +1864,12 @@
yyerror("out of memory");
free(id);
return -1;
}
- attr = hashtab_search(policydbp->p_types.table, id);
- if (!attr) {
- sprintf(errormsg, "attribute %s is not declared", id);
+ inherit = hashtab_search(policydbp->p_types.table, id);
+ if (!inherit) {
+ sprintf(errormsg, "%sattribute %s is not declared",
+ (extends)?"type/":"", id);
#if 1
/* treat it as a fatal error */
yyerror(errormsg);
return -1;
@@ -1887,18 +1896,18 @@
} else {
newattr = 0;
}
- if (!attr->isattr) {
+ if (!extends && !inherit->isattr) {
sprintf(errormsg, "%s is a type, not an attribute", id);
yyerror(errormsg);
return -1;
}
if (!newattr)
free(id);
- ebitmap_set_bit(&attr->types, datum->value - 1, TRUE);
+ ebitmap_set_bit(&inherit->types, datum->value - 1, TRUE);
}
return 0;
}
@@ -1935,16 +1944,16 @@
return v.name;
return NULL;
}
-
static int set_types(ebitmap_t *set,
ebitmap_t *negset,
char *id,
int *add)
{
type_datum_t *t;
unsigned int i;
+ ebitmap_t temp;
if (strcmp(id, "*") == 0) {
/* set all types not in negset */
for (i = 0; i < policydbp->p_types.nprim; i++) {
@@ -1980,43 +1989,27 @@
free(id);
return -1;
}
- if (t->isattr) {
- /* set or clear all types with this attribute,
- but do not set anything explicitly cleared previously */
- for (i = ebitmap_startbit(&t->types); i < ebitmap_length(&t->types); i++) {
- if (!ebitmap_get_bit(&t->types, i))
- continue;
- if (!(*add)) {
- ebitmap_set_bit(set, i, FALSE);
- ebitmap_set_bit(negset, i, TRUE);
- } else if (!ebitmap_get_bit(negset, i)) {
- ebitmap_set_bit(set, i, TRUE);
-#if VERBOSE
- } else {
- char *name = type_val_to_name(i+1);
- sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
- yywarn(errormsg);
-#endif
- }
- }
- } else {
- /* set or clear one type, but do not set anything
- explicitly cleared previously */
+ ebitmap_init(&temp);
+ get_child_types(&temp, t, 0);
+ for (i = ebitmap_startbit(&temp); i < ebitmap_length(&temp); i++) {
+ if (!ebitmap_get_bit(&temp, i))
+ continue;
if (!(*add)) {
- ebitmap_set_bit(set, t->value - 1, FALSE);
- ebitmap_set_bit(negset, t->value - 1, TRUE);
- } else if (!ebitmap_get_bit(negset, t->value - 1)) {
- ebitmap_set_bit(set, t->value - 1, TRUE);
+ ebitmap_set_bit(set, i, FALSE);
+ ebitmap_set_bit(negset, i, TRUE);
+ } else if (!ebitmap_get_bit(negset, i)) {
+ ebitmap_set_bit(set, i, TRUE);
#if VERBOSE
} else {
- sprintf(errormsg, "ignoring %s due to prior -%s", id, id);
+ char *name = type_val_to_name(i+1);
+ sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
yywarn(errormsg);
#endif
}
}
-
+ ebitmap_destroy(&temp);
free(id);
*add = 1;
return 0;
}
@@ -2598,9 +2591,10 @@
char *id;
cond_av_list_t *sub_list, *final_list, *tail;
class_datum_t *cladatum;
perm_datum_t *perdatum;
- ebitmap_t stypes, ttypes, tclasses, negset;
+ type_datum_t *typedatum;
+ ebitmap_t stypes, ttypes, tclasses, temp, negset;
access_vector_t *avp;
int i, j, hiclass, self = 0, add = 1;
int suppress = 0;
@@ -2722,20 +2716,33 @@
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
if (!ebitmap_get_bit(&stypes, i))
continue;
if (self) {
- if ((sub_list = cond_te_avtab_helper(which, i, i, &tclasses, avp )) == COND_ERR)
+ typedatum = get_type(i+1);
+ if (!typedatum)
return COND_ERR;
- if (final_list) {
- tail->next = sub_list;
- while (tail->next != NULL)
- tail = tail->next;
- } else {
- final_list = sub_list;
- tail = final_list;
- while (tail->next != NULL)
- tail = tail->next;
+ ebitmap_init(&temp);
+ get_child_types(&temp, typedatum, 0);
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if(!ebitmap_get_bit(&temp, j))
+ continue;
+ sub_list = cond_te_avtab_helper(which, i, j, &tclasses, avp );
+ if (sub_list==COND_ERR) {
+ ebitmap_destroy(&temp);
+ return COND_ERR;
+ }
+ if (final_list) {
+ tail->next = sub_list;
+ while (tail->next != NULL)
+ tail = tail->next;
+ } else {
+ final_list = sub_list;
+ tail = final_list;
+ while (tail->next != NULL)
+ tail = tail->next;
+ }
}
+ ebitmap_destroy(&temp);
}
}
}
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
@@ -2774,9 +2781,10 @@
{
char *id;
class_datum_t *cladatum;
perm_datum_t *perdatum;
- ebitmap_t stypes, ttypes, tclasses, negset;
+ type_datum_t *typedatum;
+ ebitmap_t stypes, ttypes, tclasses, temp, negset;
access_vector_t *avp;
unsigned int i, j, hiclass;
int self = 0, add = 1;
te_assert_t *newassert;
@@ -2914,10 +2922,22 @@
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
if (!ebitmap_get_bit(&stypes, i))
continue;
if (self) {
- if (te_avtab_helper(which, i, i, &tclasses, avp))
+ typedatum = get_type(i+1);
+ if (!typedatum)
return -1;
+ ebitmap_init(&temp);
+ get_child_types(&temp, typedatum, 0);
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if (!ebitmap_get_bit(&temp, j))
+ continue;
+ if (te_avtab_helper(which, i, j, &tclasses, avp)) {
+ ebitmap_destroy(&temp);
+ return -1;
+ }
+ }
+ ebitmap_destroy(&temp);
}
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
if (!ebitmap_get_bit(&ttypes, j))
continue;
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-13 16:36 [RFC & PATCH] inherited type definition KaiGai Kohei
@ 2005-03-14 13:17 ` KaiGai Kohei
2005-03-14 13:50 ` Stephen Smalley
2005-03-14 16:38 ` Karl MacMillan
2 siblings, 0 replies; 58+ messages in thread
From: KaiGai Kohei @ 2005-03-14 13:17 UTC (permalink / raw)
To: SELinux Mail List; +Cc: kaigai
[-- Attachment #1: Type: text/plain, Size: 2526 bytes --]
Hi,
Yesterday, I posted a patch that implements "TYPE ... EXTENDS ..." statement.
But, I noticed this patch can't be applied to latest checkpolicy-1.22.
So, I modified the inherited type definition patch for latest checkpolicy.
There is no differences on functionality and compatibility.
Thanks, any comments please.
KaiGai Kohei wrote:
> Hello,
> This attached patch provids a new syntax extension to checkpolicy.
> This makes it possible to describe a definition of type which inherit
> access vectors of parent's types/attributes.
>
> Syntax:
> TYPE <type> [ALIAS <aliases>] EXTENDS <type/attr>, <type/attr>, ... ;
>
> The basical idea is like attribute, but 'EXTENDS' has those differences as follows:
> - It can inherit other types, not only attribute.
> - It can describe multi-layer inheritance tree of type.
>
> Currently, when we try to define a type like another type, we must describe a new
> type from a scratch for tiny difference. For example, if we want a new type
> 'ext_user_t' which is permitted all access vectors for user_t and a tiny additional
> access vectors, we must describe all of the user_t's access vectors and some of
> original allow-statements.
>
> When you use EXTENDS extension, only what you describe are a type definition
> with EXTENDS statement and some original allow-statements.
>
> [Simple Example]
> type subject_t;
> type parent_t;
> type child_t extends parent_t;
> type grandchild_t extends child_t;
> type stranger_t;
>
> In this case, there are five types for explanation.
> - "allow subject_t child_t:XXX XXX;" means "allow subject_t {child_t grandchild_t}:XXX XXX".
> - "allow parent_t child_t:XXX XXX;" means "allow {parent_t child_t grandchild_t} {child_t grandchild_t}:XXX XXX"
> - "allow subject_t ~parent_t:XXX XXX" means "allow subject_t stranger_t:XXX XXX".
> child_t and grandchild_t are not included in ~parent_t, because its ancestor is parent_t.
> - "allow child_t self:XXX XXX" means "allow child_t child_t:XXX XXX",
> "allow child_t grandchild_t:XXX XXX" and "allow grandchild_t grandchild_t:XXX XXX".
>
> An access vector granted to parent-type is inherited to child and grandchild.
> We must pay attention to '~' and 'self'.
> When we use '~', that means the reverse of the type and its children.
> When we use 'self', that means the type and its children.
>
> Thanks, any comments please.
> # This is a personal work, but would you Cc: 'kaigai@ak.jp.nec.com' for useful ?
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
[-- Attachment #2: checkpolicy-1.22-type_extends.patch --]
[-- Type: text/plain, Size: 12634 bytes --]
--- checkpolicy-1.22/policy_scan.l 2005-02-17 09:59:23.000000000 -0500
+++ checkpolicy-1.22.extends/policy_scan.l 2005-03-14 20:37:54.000000000 -0500
@@ -78,6 +78,8 @@ ELSE |
else { return(ELSE); }
ALIAS |
alias { return(ALIAS); }
+EXTENDS |
+extends { return(EXTENDS); }
ATTRIBUTE |
attribute { return(ATTRIBUTE); }
TYPE_TRANSITION |
--- checkpolicy-1.22/checkpolicy.h 2005-01-26 14:16:20.000000000 -0500
+++ checkpolicy-1.22.extends/checkpolicy.h 2005-03-14 20:40:12.000000000 -0500
@@ -18,4 +18,16 @@ te_assert_t *te_assertions;
extern unsigned int policyvers;
extern unsigned int mlspol;
+/* type was not indexed in policydb,
+ but it's necessary for extends support. */
+extern type_datum_t **type_val_to_struct;
+extern int num_type_val_to_struct;
+extern void get_child_types(ebitmap_t *set, type_datum_t *t, int depth);
+
+static inline type_datum_t *get_type(int typeval) {
+ if (!type_val_to_struct || typeval<1 || typeval>num_type_val_to_struct)
+ return NULL;
+ return type_val_to_struct[typeval-1];
+}
+
#endif
--- checkpolicy-1.22/checkpolicy.c 2005-01-26 14:16:20.000000000 -0500
+++ checkpolicy-1.22.extends/checkpolicy.c 2005-03-14 20:37:54.000000000 -0500
@@ -344,6 +344,8 @@ void check_assertion_helper(unsigned int
void check_assertions(void)
{
+ ebitmap_t temp;
+ type_datum_t *typedatum;
te_assert_t *a, *tmp;
unsigned int i, j;
@@ -353,7 +355,19 @@ void check_assertions(void)
if (!ebitmap_get_bit(&a->stypes, i))
continue;
if (a->self) {
- check_assertion_helper(i, i, &a->tclasses, a->avp, a->line);
+ typedatum = type_val_to_struct[i];
+ if (!typedatum) {
+ fprintf(stderr, "BUG: check_assetion for undefined type.\n");
+ exit(1);
+ }
+ ebitmap_init(&temp);
+ get_child_types(&temp, typedatum, 0);
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if (!ebitmap_get_bit(&temp, j))
+ continue;
+ check_assertion_helper(i, j, &a->tclasses, a->avp, a->line);
+ }
+ ebitmap_destroy(&temp);
}
for (j = ebitmap_startbit(&a->ttypes); j < ebitmap_length(&a->ttypes); j++) {
if (!ebitmap_get_bit(&a->ttypes, j))
@@ -442,6 +456,41 @@ int change_bool(char *name, int state)
return 0;
}
+type_datum_t **type_val_to_struct = NULL;
+int num_type_val_to_struct = -1;
+
+static int type_val_to_struct_helper(hashtab_key_t k, hashtab_datum_t d, void *args)
+{
+ type_datum_t *t = (type_datum_t *)d;
+ if (!t->isattr && t->primary)
+ type_val_to_struct[t->value-1] = t;
+ return 0; /* always success */
+}
+
+void get_child_types(ebitmap_t *set, type_datum_t *td, int depth)
+{
+ type_datum_t *child;
+ int i;
+
+ if (td->isattr && depth>0) {
+ fprintf(stderr, "BUG: an attribute must not inherit anyone.\n");
+ exit(1);
+ }
+
+ if (!td->isattr && !td->primary)
+ td = get_type(td->value);
+
+ if (!td->isattr)
+ ebitmap_set_bit(set, td->value - 1, 1);
+
+ for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+ if (ebitmap_get_bit(&td->types, i)) {
+ child = type_val_to_struct[i];
+ get_child_types(set, child, depth + 1);
+ }
+ }
+}
+
int main(int argc, char **argv)
{
security_class_t tclass;
@@ -456,7 +505,7 @@ int main(int argc, char **argv)
unsigned int binary = 0, debug = 0;
struct val_to_name v;
int ret, ch, fd;
- unsigned int nel;
+ unsigned int nel, len;
struct stat sb;
void *map;
FILE *outfp = NULL;
@@ -593,6 +642,18 @@ int main(int argc, char **argv)
fprintf(stderr, "%s: error(s) encountered while parsing configuration\n", argv[0]);
exit(1);
}
+
+ /* construction of type_val_to_struct */
+ num_type_val_to_struct = policydbp->p_types.nprim;
+ len = sizeof(type_datum_t *) * num_type_val_to_struct;
+ type_val_to_struct = (type_datum_t **)malloc(len);
+ if (!type_val_to_struct) {
+ fprintf(stderr, "type_val_to_struct: out of memory\n");
+ exit(1);
+ }
+ memset(type_val_to_struct, 0, len);
+ hashtab_map(policydbp->p_types.table, type_val_to_struct_helper, NULL);
+
rewind(yyin);
policydb_lineno = 1;
source_file[0] = '\0';
--- checkpolicy-1.22/policy_parse.y 2005-02-17 09:59:23.000000000 -0500
+++ checkpolicy-1.22.extends/policy_parse.y 2005-03-14 20:46:25.000000000 -0500
@@ -19,6 +19,11 @@
* the Free Software Foundation, version 2.
*/
+/* Updated: KaiGai Kohei, <kaigai@ak.jp.nec.com>
+ * Added inherited type extensions. (2005/03/13)
+ */
+
+
/* FLASK */
%{
@@ -73,7 +78,7 @@ static int define_level(int range);
static int define_attrib(void);
static int define_typealias(void);
static int define_typeattribute(void);
-static int define_type(int alias);
+static int define_type(int alias, int extends);
static int define_compute_type(int which);
static int define_te_avtab(int which);
static int define_role_types(void);
@@ -133,6 +138,7 @@ static int define_ipv6_node_context(void
%token TYPE
%token TYPES
%token ALIAS
+%token EXTENDS
%token ATTRIBUTE
%token BOOL
%token IF
@@ -297,9 +303,13 @@ attribute_def : ATTRIBUTE iden
{ if (define_attrib()) return -1;}
;
type_def : TYPE identifier alias_def opt_attr_list ';'
- {if (define_type(1)) return -1;}
+ {if (define_type(1, 0)) return -1;}
| TYPE identifier opt_attr_list ';'
- {if (define_type(0)) return -1;}
+ {if (define_type(0, 0)) return -1;}
+ | TYPE identifier alias_def opt_extends_list ';'
+ {if (define_type(1, 1)) return -1;}
+ | TYPE identifier opt_extends_list ';'
+ {if (define_type(0, 1)) return -1;}
;
typealias_def : TYPEALIAS identifier alias_def ';'
{if (define_typealias()) return -1;}
@@ -310,6 +320,8 @@ typeattribute_def : TYPEATTRIBUTE identi
opt_attr_list : ',' id_comma_list
|
;
+opt_extends_list : EXTENDS id_comma_list
+ ;
bool_def : BOOL identifier bool_val ';'
{if (define_bool()) return -1;}
;
@@ -1529,13 +1541,11 @@ static int define_typealias(void)
if (ret == HASHTAB_PRESENT) {
sprintf(errormsg, "name conflict for type alias %s", id);
yyerror(errormsg);
- free(aliasdatum);
free(id);
return -1;
}
if (ret == HASHTAB_OVERFLOW) {
yyerror("hash table overflow");
- free(aliasdatum);
free(id);
return -1;
}
@@ -1596,10 +1606,10 @@ static int define_typeattribute(void)
return 0;
}
-static int define_type(int alias)
+static int define_type(int alias, int extends)
{
char *id;
- type_datum_t *datum, *aliasdatum, *attr;
+ type_datum_t *datum, *aliasdatum, *inherit;
int ret, newattr = 0;
@@ -1663,13 +1673,11 @@ static int define_type(int alias)
if (ret == HASHTAB_PRESENT) {
sprintf(errormsg, "name conflict for type alias %s", id);
yyerror(errormsg);
- free(aliasdatum);
free(id);
return -1;
}
if (ret == HASHTAB_OVERFLOW) {
yyerror("hash table overflow");
- free(aliasdatum);
free(id);
return -1;
}
@@ -1677,9 +1685,10 @@ static int define_type(int alias)
}
while ((id = queue_remove(id_queue))) {
- attr = hashtab_search(policydbp->p_types.table, id);
- if (!attr) {
- sprintf(errormsg, "attribute %s is not declared", id);
+ inherit = hashtab_search(policydbp->p_types.table, id);
+ if (!inherit) {
+ sprintf(errormsg, "%sattribute %s is not declared",
+ (extends)?"type/":"", id);
#if 1
/* treat it as a fatal error */
yyerror(errormsg);
@@ -1708,7 +1717,7 @@ static int define_type(int alias)
newattr = 0;
}
- if (!attr->isattr) {
+ if (!extends && !inherit->isattr) {
sprintf(errormsg, "%s is a type, not an attribute", id);
yyerror(errormsg);
return -1;
@@ -1717,7 +1726,7 @@ static int define_type(int alias)
if (!newattr)
free(id);
- ebitmap_set_bit(&attr->types, datum->value - 1, TRUE);
+ ebitmap_set_bit(&inherit->types, datum->value - 1, TRUE);
}
return 0;
@@ -1756,7 +1765,6 @@ static char *type_val_to_name(unsigned i
return NULL;
}
-
static int set_types(ebitmap_t *set,
ebitmap_t *negset,
char *id,
@@ -1764,6 +1772,7 @@ static int set_types(ebitmap_t *set,
{
type_datum_t *t;
unsigned int i;
+ ebitmap_t temp;
if (strcmp(id, "*") == 0) {
/* set all types not in negset */
@@ -1801,41 +1810,25 @@ static int set_types(ebitmap_t *set,
return -1;
}
- if (t->isattr) {
- /* set or clear all types with this attribute,
- but do not set anything explicitly cleared previously */
- for (i = ebitmap_startbit(&t->types); i < ebitmap_length(&t->types); i++) {
- if (!ebitmap_get_bit(&t->types, i))
- continue;
- if (!(*add)) {
- ebitmap_set_bit(set, i, FALSE);
- ebitmap_set_bit(negset, i, TRUE);
- } else if (!ebitmap_get_bit(negset, i)) {
- ebitmap_set_bit(set, i, TRUE);
-#if VERBOSE
- } else {
- char *name = type_val_to_name(i+1);
- sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
- yywarn(errormsg);
-#endif
- }
- }
- } else {
- /* set or clear one type, but do not set anything
- explicitly cleared previously */
+ ebitmap_init(&temp);
+ get_child_types(&temp, t, 0);
+ for (i = ebitmap_startbit(&temp); i < ebitmap_length(&temp); i++) {
+ if (!ebitmap_get_bit(&temp, i))
+ continue;
if (!(*add)) {
- ebitmap_set_bit(set, t->value - 1, FALSE);
- ebitmap_set_bit(negset, t->value - 1, TRUE);
- } else if (!ebitmap_get_bit(negset, t->value - 1)) {
- ebitmap_set_bit(set, t->value - 1, TRUE);
+ ebitmap_set_bit(set, i, FALSE);
+ ebitmap_set_bit(negset, i, TRUE);
+ } else if (!ebitmap_get_bit(negset, i)) {
+ ebitmap_set_bit(set, i, TRUE);
#if VERBOSE
} else {
- sprintf(errormsg, "ignoring %s due to prior -%s", id, id);
+ char *name = type_val_to_name(i+1);
+ sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
yywarn(errormsg);
#endif
}
}
-
+ ebitmap_destroy(&temp);
free(id);
*add = 1;
return 0;
@@ -2419,7 +2412,8 @@ static cond_av_list_t *define_cond_te_av
cond_av_list_t *sub_list, *final_list, *tail;
class_datum_t *cladatum;
perm_datum_t *perdatum;
- ebitmap_t stypes, ttypes, tclasses, negset;
+ type_datum_t *typedatum;
+ ebitmap_t stypes, ttypes, tclasses, temp, negset;
access_vector_t *avp;
int i, j, hiclass, self = 0, add = 1;
int suppress = 0;
@@ -2543,18 +2537,31 @@ static cond_av_list_t *define_cond_te_av
if (!ebitmap_get_bit(&stypes, i))
continue;
if (self) {
- if ((sub_list = cond_te_avtab_helper(which, i, i, &tclasses, avp )) == COND_ERR)
+ typedatum = get_type(i+1);
+ if (!typedatum)
return COND_ERR;
- if (final_list) {
- tail->next = sub_list;
- while (tail->next != NULL)
- tail = tail->next;
- } else {
- final_list = sub_list;
- tail = final_list;
- while (tail->next != NULL)
- tail = tail->next;
+ ebitmap_init(&temp);
+ get_child_types(&temp, typedatum, 0);
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if(!ebitmap_get_bit(&temp, j))
+ continue;
+ sub_list = cond_te_avtab_helper(which, i, j, &tclasses, avp );
+ if (sub_list==COND_ERR) {
+ ebitmap_destroy(&temp);
+ return COND_ERR;
+ }
+ if (final_list) {
+ tail->next = sub_list;
+ while (tail->next != NULL)
+ tail = tail->next;
+ } else {
+ final_list = sub_list;
+ tail = final_list;
+ while (tail->next != NULL)
+ tail = tail->next;
+ }
}
+ ebitmap_destroy(&temp);
}
}
}
@@ -2595,7 +2602,8 @@ static int define_te_avtab(int which)
char *id;
class_datum_t *cladatum;
perm_datum_t *perdatum;
- ebitmap_t stypes, ttypes, tclasses, negset;
+ type_datum_t *typedatum;
+ ebitmap_t stypes, ttypes, tclasses, temp, negset;
access_vector_t *avp;
unsigned int i, j, hiclass;
int self = 0, add = 1;
@@ -2735,8 +2743,20 @@ static int define_te_avtab(int which)
if (!ebitmap_get_bit(&stypes, i))
continue;
if (self) {
- if (te_avtab_helper(which, i, i, &tclasses, avp))
+ typedatum = get_type(i+1);
+ if (!typedatum)
return -1;
+ ebitmap_init(&temp);
+ get_child_types(&temp, typedatum, 0);
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if (!ebitmap_get_bit(&temp, j))
+ continue;
+ if (te_avtab_helper(which, i, j, &tclasses, avp)) {
+ ebitmap_destroy(&temp);
+ return -1;
+ }
+ }
+ ebitmap_destroy(&temp);
}
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
if (!ebitmap_get_bit(&ttypes, j))
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-13 16:36 [RFC & PATCH] inherited type definition KaiGai Kohei
2005-03-14 13:17 ` KaiGai Kohei
@ 2005-03-14 13:50 ` Stephen Smalley
2005-03-14 15:13 ` Luke Kenneth Casson Leighton
2005-03-14 17:26 ` KaiGai Kohei
2005-03-14 16:38 ` Karl MacMillan
2 siblings, 2 replies; 58+ messages in thread
From: Stephen Smalley @ 2005-03-14 13:50 UTC (permalink / raw)
To: KaiGai Kohei; +Cc: SELinux Mail List, kaigai
On Mon, 2005-03-14 at 01:36 +0900, KaiGai Kohei wrote:
> This attached patch provids a new syntax extension to checkpolicy.
> This makes it possible to describe a definition of type which inherit
> access vectors of parent's types/attributes.
Thanks for creating this patch, as there does seem to be renewed
interest in such a feature. I haven't looked closely at it yet, but
wanted to mention that we used to have a "clone" statement in the policy
language that could be used to clone all TE rules from one domain into
another domain, but we ultimately dropped it because we didn't think
that it was the right approach, and that the ability to define shared
sets of permissions among domains via macros was preferable to allow
tailoring of the shared set to specific needs. Some specific issues
with supporting such a feature in the base language were:
1) Should the child domain inherit all rules that involved the parent
domain at all, or only rules where the parent domain was the
source/subject in the rule? It looks like you have chosen the former,
but this means that any domain that can act on the parent domain can act
in the same manner on the child domain directly; not clear that this is
always what you want.
2) Should the child domain inherit rules between the parent and the
child, i.e. should the child be able to do anything to itself that the
parent can do to it? It looks like you are inheriting such rules, but
is this always desirable, e.g. the parent may need permissions to set up
the child, control it, kill it, etc that the child may not need to
itself.
3) What should happen with rules between the parent and itself? It
looks like you are translating "self" rules to only involve the child
and its descendants, but this would still mean that any explicit rule of
the form "allow parent_t parent_t:process sigkill;" would be inherited
by the child, i.e. "allow child_t parent_t:process sigkill;", right?
4) What should happen with transition rules that involve the parent? In
some cases, you will likely want to inherit them, but in others, you may
want the child to transition to a separate derived domain from the one
used by the parent.
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-14 13:50 ` Stephen Smalley
@ 2005-03-14 15:13 ` Luke Kenneth Casson Leighton
2005-03-14 15:22 ` Stephen Smalley
2005-03-14 17:26 ` KaiGai Kohei
1 sibling, 1 reply; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-14 15:13 UTC (permalink / raw)
To: Stephen Smalley; +Cc: KaiGai Kohei, SELinux Mail List, kaigai
On Mon, Mar 14, 2005 at 08:50:02AM -0500, Stephen Smalley wrote:
> 3) What should happen with rules between the parent and itself? It
> looks like you are translating "self" rules to only involve the child
> and its descendants, but this would still mean that any explicit rule of
> the form "allow parent_t parent_t:process sigkill;" would be inherited
> by the child, i.e. "allow child_t parent_t:process sigkill;", right?
i would expect syntax allow parent_t self:process sigkill to
be inherited to "allow child_t self:process sigkill"
and expect "allow parent_t parent_t:process sigkill to
be inherited to "allow child_t parent_t:process sigkill"
except that wouldn't work if there's a "special" meaning given
to "self:".
there's no special meaning given to self: is there?
it's just for convenience in case you want to change the name
of the domain, isn't it?
> 4) What should happen with transition rules that involve the parent? In
> some cases, you will likely want to inherit them, but in others, you may
> want the child to transition to a separate derived domain from the one
> used by the parent.
subdivide the parent domain into rules which you do want to be
inherited, and those that you do not.
derive a child domain that gives you the original one, so you
don't have any code uses to change.
derive other domains from the smaller parent one.
5) what about multiple inheritance?
syntax should allow for such - to combine two parent
sets into one child domain.
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-14 15:13 ` Luke Kenneth Casson Leighton
@ 2005-03-14 15:22 ` Stephen Smalley
2005-03-14 16:01 ` Luke Kenneth Casson Leighton
0 siblings, 1 reply; 58+ messages in thread
From: Stephen Smalley @ 2005-03-14 15:22 UTC (permalink / raw)
To: Luke Kenneth Casson Leighton; +Cc: KaiGai Kohei, SELinux Mail List, kaigai
On Mon, 2005-03-14 at 15:13 +0000, Luke Kenneth Casson Leighton wrote:
> i would expect syntax allow parent_t self:process sigkill to
> be inherited to "allow child_t self:process sigkill"
>
> and expect "allow parent_t parent_t:process sigkill to
> be inherited to "allow child_t parent_t:process sigkill"
I would not expect there to be any difference, as self is just a
convenience notation, and in this particular example, someone who writes
either form likely would not want the child to be able to kill the
parent without an explicit allow rule from the child to the parent.
> except that wouldn't work if there's a "special" meaning given
> to "self:".
The policy compiler can (and does) distinguish self for processing, e.g.
allow domain self:process sigkill;
expands to what you would expect, i.e.
allow domain0_t domain0_t:process sigkill;
allow domain1_t domain1_t:process sigkill;
...
Hence, the policy compiler can handle self differently if desired, but
in this case, I don't think we want it to be handled differently.
> subdivide the parent domain into rules which you do want to be
> inherited, and those that you do not.
>
> derive a child domain that gives you the original one, so you
> don't have any code uses to change.
>
> derive other domains from the smaller parent one.
Yes, but if you are willing to refactor existing domains in this manner,
then it is unclear that you gain much benefit from having the
inheritance support (vs. just defining macros that partition the domain
in the same manner, and only including the desired macros in the "child"
domains).
> 5) what about multiple inheritance?
>
> syntax should allow for such - to combine two parent
> sets into one child domain.
I think that KaiGai's patch allows for such multiple inheritance, but
think about the implications there for type transition rules - what
happens if they have a different default transition on the same
executable type?
If you look at existing derived domains for programs, you'll see that
they don't fall neatly into this kind of inheritance scheme, as they
gain some permissions that aren't directly allowed to the user domain
and drop some permissions (and most/all transitions) possessed by the
user domain that the program doesn't need.
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-14 15:22 ` Stephen Smalley
@ 2005-03-14 16:01 ` Luke Kenneth Casson Leighton
2005-03-14 19:27 ` Valdis.Kletnieks
2005-03-14 20:10 ` Stephen Smalley
0 siblings, 2 replies; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-14 16:01 UTC (permalink / raw)
To: Stephen Smalley; +Cc: KaiGai Kohei, SELinux Mail List, kaigai
sounds all-in-all like a "partial" inheritance is needed, which
refactoring would give you - but not in an ideal fashion.
i've never ever heard of any object orientated system
_excluding_ certain functionality of the parent on inheritance
[has anyone else?]
i've heard of public, protected and private interfaces - but
never of exclusion: always, refactoring is used.
seriously considering the provision of some partial inheritance
reminds me of the spoof languages article that was making the
rounds in about 1989 - the one with "SLOBOL" - which amongst
other things described some extensions to BASIC. a "GO FROM"
construct, which would periodically attempt to pinch program
control from a line, and try to undo some of the commands if
it missed.
so.
what is the one significant distinct advantage that the proposed
inheritance thing gives you that macro refactoring cannot?
my guess would be on how handling of "self" was made to work.
On Mon, Mar 14, 2005 at 10:22:12AM -0500, Stephen Smalley wrote:
> On Mon, 2005-03-14 at 15:13 +0000, Luke Kenneth Casson Leighton wrote:
> > i would expect syntax allow parent_t self:process sigkill to
> > be inherited to "allow child_t self:process sigkill"
> >
> > and expect "allow parent_t parent_t:process sigkill to
> > be inherited to "allow child_t parent_t:process sigkill"
>
> I would not expect there to be any difference, as self is just a
> convenience notation, and in this particular example, someone who writes
> either form likely would not want the child to be able to kill the
> parent without an explicit allow rule from the child to the parent.
can i suggest having a policy checker similar to "lint" which would
warn users of such, in instances where a developer inherits "self"
rules rather than "allow parent_t parent_t:.... ...." rules?
or ... to make the compiler tools spit out a warning which needs
to be explicitly disabled with a --no-warn-inherit-allow-self
option or something?
> > except that wouldn't work if there's a "special" meaning given
> > to "self:".
>
> The policy compiler can (and does) distinguish self for processing, e.g.
> allow domain self:process sigkill;
> expands to what you would expect, i.e.
> allow domain0_t domain0_t:process sigkill;
> allow domain1_t domain1_t:process sigkill;
> ...
ahh. yes, of course. i always wondered what made self: particularly
needed.
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-13 16:36 [RFC & PATCH] inherited type definition KaiGai Kohei
2005-03-14 13:17 ` KaiGai Kohei
2005-03-14 13:50 ` Stephen Smalley
@ 2005-03-14 16:38 ` Karl MacMillan
2005-03-15 11:47 ` KaiGai Kohei
2 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2005-03-14 16:38 UTC (permalink / raw)
To: 'KaiGai Kohei', 'SELinux Mail List'; +Cc: kaigai, selinux-dev
> -----Original Message-----
> From: owner-selinux@tycho.nsa.gov
> [mailto:owner-selinux@tycho.nsa.gov] On Behalf Of KaiGai Kohei
> Sent: Sunday, March 13, 2005 11:37 AM
> To: SELinux Mail List
> Cc: kaigai@ak.jp.nec.com
> Subject: [RFC & PATCH] inherited type definition.
>
> Hello,
> This attached patch provids a new syntax extension to checkpolicy.
> This makes it possible to describe a definition of type which
> inherit access vectors of parent's types/attributes.
>
> Syntax:
> TYPE <type> [ALIAS <aliases>] EXTENDS <type/attr>, <type/attr>, ... ;
>
> The basical idea is like attribute, but 'EXTENDS' has those
> differences as follows:
> - It can inherit other types, not only attribute.
> - It can describe multi-layer inheritance tree of type.
>
Interesting patch and I'm glad to see you use sediff for testing this - it has
proven very valuable to use when doing work on checkpolicy for us as well. My
concern for this (in addition to Steve's comments) is that it isn't general
enough to solve many of the policy language problems that we commonly see. For
example, this doesn't help with types that are derived on a per-role basis. This
is a conceptually similar problem - I want user_ssh_t to be very similar
staff_ssh_t with some differences - but requires some additional features. I am
interested in extending this because right now it is not possible to easily add
roles to binary policies, like the modules, because the per-role types are not
correctly created.
I don't have a concrete suggestion, but an example would be a policy syntax that
could duplicate the ssh_domain macro. Instead of creating a type based on
another type, it would be creating a type based on a 'type template'. This would
allow creating user_ssh_t and staff_ssh_t, for example, with similar access in
many cases, but also differences (e.g., user_home_ssh_t and staff_home_ssh_t or
a different transition from ssh_exec_t).
Comments?
Karl
---
Karl MacMillan
Tresys Technology
http://www.tresys.com
(410) 290-1411 ext 134
> Currently, when we try to define a type like another type, we
> must describe a new type from a scratch for tiny difference.
> For example, if we want a new type 'ext_user_t' which is
> permitted all access vectors for user_t and a tiny additional
> access vectors, we must describe all of the user_t's access
> vectors and some of original allow-statements.
>
> When you use EXTENDS extension, only what you describe are a
> type definition with EXTENDS statement and some original
> allow-statements.
>
> [Simple Example]
> type subject_t;
> type parent_t;
> type child_t extends parent_t;
> type grandchild_t extends child_t;
> type stranger_t;
>
> In this case, there are five types for explanation.
> - "allow subject_t child_t:XXX XXX;" means "allow subject_t
> {child_t grandchild_t}:XXX XXX".
> - "allow parent_t child_t:XXX XXX;" means "allow {parent_t
> child_t grandchild_t} {child_t grandchild_t}:XXX XXX"
> - "allow subject_t ~parent_t:XXX XXX" means "allow subject_t
> stranger_t:XXX XXX".
> child_t and grandchild_t are not included in ~parent_t,
> because its ancestor is parent_t.
> - "allow child_t self:XXX XXX" means "allow child_t child_t:XXX XXX",
> "allow child_t grandchild_t:XXX XXX" and "allow
> grandchild_t grandchild_t:XXX XXX".
>
> An access vector granted to parent-type is inherited to child
> and grandchild.
> We must pay attention to '~' and 'self'.
> When we use '~', that means the reverse of the type and its children.
> When we use 'self', that means the type and its children.
>
> Thanks, any comments please.
> # This is a personal work, but would you Cc:
> 'kaigai@ak.jp.nec.com' for useful ?
>
> --------------------------------------------------------------------
> When we don't use EXTENDS statement, checkpolicy works compatibly.
> I tried to test checkpolicy-1.20 with EXTENDS patch by
> Tresys's sediff and policy-1.20.
>
> Test 1: compatibility of the checkpolicy [kaigai@ayu ~]$
> sediff polbin.org polbin.std Difference between policy 1 and policy 2:
> p1 (binary, ver: 18): polbin.org ... generated by standard
> checkpolicy
> p2 (binary, ver: 18): polbin.std ... generated by extended
> checkpolicy
>
> Types (0 Added, 0 Removed, 0 Changed)
> Added Types: 0
> Removed Types: 0
> Changed Types: 0
>
> Roles (0 Added, 0 Removed, 0 Changed)
> Added Roles: 0
> Removed Roles: 0
> Changed Roles: 0
>
> Users (0 Added, 0 Removed, 0 Changed)
> Added Users: 0
> Removed Users: 0
> Changed Users: 0
>
> Booleans (0 Added, 0 Removed, 0 Changed)
> Added Booleans: 0
> Removed Booleans: 0
> Changed Booleans: 0
>
> Classes (0 Added, 0 Removed, 0 Changed)
> Added Classes: 0
> Removed Classes: 0
> Changed Classes: 0
>
> Permissions (0 Added, 0 Removed)
> Added Permissions: 0
> Removed Permissions: 0
>
> Common Permissions (0 Added, 0 Removed, 0 Changed)
> Added Common Permissions: 0
> Removed Common Permissions: 0
> Changed Common Permissions: 0
>
> Conditionals are not currently supported.
> Role Allows (0 Added, 0 Removed, 0 Changed)
> Added Role Allows: 0
> Removed Role Allows: 0
> Changed Role Allows: 0
>
> TE Rules (0 Added, 0 Removed, 0 Changed)
> Added TE Rules 0:
> Removed TE Rules 0:
> Changed TE Rules 0:
>
> Total Differences:
> Classes & Permissions 0
> Types 0
> Attributes 0
> Roles 0
> Users 0
> Booleans 0
> Rbac 0
> TE Rules 0
>
> --------------------------------------------------------------
> ------------
> Test 2: The advantage of EXTENDS statement.
> I added a line 'type user_ext_t extends user_t;' into
> policy.conf.
> [kaigai@ayu ~]$ sediff polbin.std polbin.ext Difference
> between policy 1 and policy 2:
> p1 (binary, ver: 18): polbin.std ... original policy-1.20
> p2 (binary, ver: 18): polbin.ext ... I added a type definition.
>
> Types (1 Added, 0 Removed, 0 Changed)
> Added Types: 1
> + user_ext_t
> Removed Types: 0
> Changed Types: 0
>
> Roles (0 Added, 0 Removed, 1 Changed)
> Added Roles: 0
> Removed Roles: 0
> Changed Roles: 1
> * user_r (1 Added Types)
> + user_ext_t
>
> Users (0 Added, 0 Removed, 0 Changed)
> :
> <Omitted>
> :
> TE Rules (1766 Added, 0 Removed, 0 Changed)
> Added TE Rules 1766:
> + allow load_policy_t user_ext_t : fd { use };
> :
> <Omitted>
> :
> + allow ifconfig_t user_ext_t : fd { use };
> Removed TE Rules 0:
> Changed TE Rules 0:
>
> Total Differences:
> Classes & Permissions 0
> Types 1
> Attributes 0
> Roles 1
> Users 0
> Booleans 0
> Rbac 0
> TE Rules 1766
>
> --
> DO NOTHING IS THE WORST POLICY.
> KaiGai Kohei <kaigai@kaigai.gr.jp>
>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-14 13:50 ` Stephen Smalley
2005-03-14 15:13 ` Luke Kenneth Casson Leighton
@ 2005-03-14 17:26 ` KaiGai Kohei
2005-03-14 18:10 ` Luke Kenneth Casson Leighton
2005-03-14 18:25 ` Stephen Smalley
1 sibling, 2 replies; 58+ messages in thread
From: KaiGai Kohei @ 2005-03-14 17:26 UTC (permalink / raw)
To: Stephen Smalley; +Cc: SELinux Mail List, kaigai
Hello, Thanks for your comments.
> 1) Should the child domain inherit all rules that involved the parent
> domain at all, or only rules where the parent domain was the
> source/subject in the rule? It looks like you have chosen the former,
> but this means that any domain that can act on the parent domain can act
> in the same manner on the child domain directly; not clear that this is
> always what you want.
In my patch, child domain/type inherit all rules including target/object
and area of ROLE clearly, not only source/subject.
(Those source/target is also included in TYPE_TRANSITION statements.)
Any permissions to parent means permissions to child/descendant concurrently.
> 2) Should the child domain inherit rules between the parent and the
> child, i.e. should the child be able to do anything to itself that the
> parent can do to it? It looks like you are inheriting such rules, but
> is this always desirable, e.g. the parent may need permissions to set up
> the child, control it, kill it, etc that the child may not need to
> itself.
When parent has permissions to himself, child also has permissions to his
parent and himself(child). In my patch, to inherit type/domain always expand
descendant's permissions. I intend to define a child type/domain which has
tiny larger permission than own parent low cost.
I think definition of reductive permission child-type/domain is the next
action assignment. If child does not need a part of the parent's permissions,
those should be revoked by DENY statement for example.
> 3) What should happen with rules between the parent and itself? It
> looks like you are translating "self" rules to only involve the child
> and its descendants, but this would still mean that any explicit rule of
> the form "allow parent_t parent_t:process sigkill;" would be inherited
> by the child, i.e. "allow child_t parent_t:process sigkill;", right?
It's a bit wrong.
When child_t inherit parent_t, "allow parent_t parent_t:process sigkill;"
is unrolled to "allow {parent_t child_t} {parent_t child_t}:process sigkill;"
The number of conbination is 4.
"allow parent_t self:process sigkill;" is unrolled as follows:
"allow parent_t parent_t:process sigkill;"
"allow parent_t child_t:process sigkill;"
"allow child_t child_t:process sigkill;"
child_t is dealt as self-domain from parent_t's viewpoint.
But parent_t is not dealed as self-domain from child_t's viewpoint,
because child_t has divaricated from parent_t yet.
This is my opinion, others may have different aspect to 'self'.
We should collect up how to deal 'self' on type-inheritance-tree, I think.
> 4) What should happen with transition rules that involve the parent? In
> some cases, you will likely want to inherit them, but in others, you may
> want the child to transition to a separate derived domain from the one
> used by the parent.
parent_t/child_t shares same transition rule for same exec type.
Maybe, any kind of overriding semantics is necessary.
Thanks.
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-14 17:26 ` KaiGai Kohei
@ 2005-03-14 18:10 ` Luke Kenneth Casson Leighton
2005-03-14 18:25 ` Stephen Smalley
1 sibling, 0 replies; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-14 18:10 UTC (permalink / raw)
To: KaiGai Kohei; +Cc: Stephen Smalley, SELinux Mail List, kaigai
On Tue, Mar 15, 2005 at 02:26:15AM +0900, KaiGai Kohei wrote:
> Hello, Thanks for your comments.
>
> > 1) Should the child domain inherit all rules that involved the parent
> > domain at all, or only rules where the parent domain was the
> > source/subject in the rule? It looks like you have chosen the former,
> > but this means that any domain that can act on the parent domain can act
> > in the same manner on the child domain directly; not clear that this is
> > always what you want.
>
> In my patch, child domain/type inherit all rules including target/object
> and area of ROLE clearly, not only source/subject.
> (Those source/target is also included in TYPE_TRANSITION statements.)
> Any permissions to parent means permissions to child/descendant concurrently.
>
>
> > 2) Should the child domain inherit rules between the parent and the
> > child, i.e. should the child be able to do anything to itself that the
> > parent can do to it? It looks like you are inheriting such rules, but
> > is this always desirable, e.g. the parent may need permissions to set up
> > the child, control it, kill it, etc that the child may not need to
> > itself.
>
> When parent has permissions to himself, child also has permissions to his
> parent and himself(child). In my patch, to inherit type/domain always expand
> descendant's permissions. I intend to define a child type/domain which has
> tiny larger permission than own parent low cost.
>
> I think definition of reductive permission child-type/domain is the next
> action assignment. If child does not need a part of the parent's permissions,
> those should be revoked by DENY statement for example.
oh dear.
reminds me of the "GO FROM" statement.
ideas:
1) "wrap" bits of a domain policy in some syntax extension with
oh i dunno a codeword "inheritable".
inheritable {
allow ....
};
this idea inspired by the c++ "public/private/protected"
system although of course it's nowhere near the same: c++
doesn't have a concept of excluding bits of a class for
inheritance.
2) explicitly specify, post-child-domain creation, with DENY
statements, those bits which should not be inherited.
3) do nothing: expect developers to refactor.
3) stephen has already explained that he does not favour
it because if you're going to bother refactor, you might as
well do it with existing macro syntax.
i responded to this by asking what benefits inheritance brings
that macro refactoring doesn't: if there aren't any, why bother
with the concept of inheritance at all?
2) smells of the joke language extensions to BASIC - "GO FROM".
sorry - but it does :)
give with one hand, then take away with the other _after_
the fact. i think this is a bad idea.
1) is a minimised version of 3) where you wouldn't actually
modify any names of any _existing_ policy types, just
place a "wrap" around them to say which bits it's okay
for child domains to inherit.
l.
--
--
<a href="http://lkcl.net">http://lkcl.net</a>
--
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-14 17:26 ` KaiGai Kohei
2005-03-14 18:10 ` Luke Kenneth Casson Leighton
@ 2005-03-14 18:25 ` Stephen Smalley
2005-03-15 11:50 ` KaiGai Kohei
1 sibling, 1 reply; 58+ messages in thread
From: Stephen Smalley @ 2005-03-14 18:25 UTC (permalink / raw)
To: KaiGai Kohei; +Cc: SELinux Mail List, kaigai
On Tue, 2005-03-15 at 02:26 +0900, KaiGai Kohei wrote:
> In my patch, child domain/type inherit all rules including target/object
> and area of ROLE clearly, not only source/subject.
> (Those source/target is also included in TYPE_TRANSITION statements.)
> Any permissions to parent means permissions to child/descendant concurrently.
<snip>
> When parent has permissions to himself, child also has permissions to his
> parent and himself(child). In my patch, to inherit type/domain always expand
> descendant's permissions. I intend to define a child type/domain which has
> tiny larger permission than own parent low cost.
This makes sense for unifying file types, as in the earlier multiple
contexts thread. I'm not sure I see how it is useful for domains; any
permissions allowed to the child domain can be indirectly gained by the
parent domain (or any domain which can control the parent domain) and
any program executables that can be used to enter the parent domain can
be used to enter the child domain, so you might as well just directly
allow the permissions to the parent domain. As a trivial example, if
you declare 'type user_ext_t extends user_t;', then user_t gets ptrace
permission to user_ext_t because it has ptrace permission to itself, so
any user_t process has full control over user_ext_t and can thus
exercise its permissions at will.
> I think definition of reductive permission child-type/domain is the next
> action assignment. If child does not need a part of the parent's permissions,
> those should be revoked by DENY statement for example.
Hmmm...given the way in which you are computing inheritance, it seems
that it could be very easy to miss something being implicitly allowed
and fail to define a corresponding deny statement. Maintainability also
becomes a problem as you have to reassess the deny rules whenever a new
allow rule is added. And we need to consider not only limiting the
child, but limiting the parent from controlling the child, if we are
going to allow more permissions to the child than the parent.
> When child_t inherit parent_t, "allow parent_t parent_t:process sigkill;"
> is unrolled to "allow {parent_t child_t} {parent_t child_t}:process sigkill;"
> The number of conbination is 4.
>
> "allow parent_t self:process sigkill;" is unrolled as follows:
> "allow parent_t parent_t:process sigkill;"
> "allow parent_t child_t:process sigkill;"
> "allow child_t child_t:process sigkill;"
The latter is more in line with what I would expect, and regardless, I
think that they should be unrolled consistently regardless of whether
the allow rule was written with "self" or explicitly with the same
domain (or an attribute that included the domain); self was purely
intended as a convenience notation and a way to express the self
relationship when using an attribute/set for the source type.
> parent_t/child_t shares same transition rule for same exec type.
> Maybe, any kind of overriding semantics is necessary.
Typically, when creating a derived domain (e.g. for a program run by a
user domain), we don't want to inherit any of the transition rules of
the base user domain. A template-based approach as suggested by Karl
seems necessary here, effectively turning the existing macro constructs
into a language feature.
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-14 16:01 ` Luke Kenneth Casson Leighton
@ 2005-03-14 19:27 ` Valdis.Kletnieks
2005-03-14 20:10 ` Stephen Smalley
1 sibling, 0 replies; 58+ messages in thread
From: Valdis.Kletnieks @ 2005-03-14 19:27 UTC (permalink / raw)
To: Luke Kenneth Casson Leighton
Cc: Stephen Smalley, KaiGai Kohei, SELinux Mail List, kaigai
[-- Attachment #1: Type: text/plain, Size: 965 bytes --]
On Mon, 14 Mar 2005 16:01:58 GMT, Luke Kenneth Casson Leighton said:
> seriously considering the provision of some partial inheritance
> reminds me of the spoof languages article that was making the
> rounds in about 1989 - the one with "SLOBOL" - which amongst
> other things described some extensions to BASIC. a "GO FROM"
> construct,
I believe INTERCAL had the 'COME FROM' construct before 1989, and the IBM
Fortran IV F, G and H compilers had the 'DEBUG' facility in the mid-70s, which
allowed the use of 'AT NNNN' blocks that did a 'COME FROM' functionality to
steal control and presumably do debugging-type stuff. Pretty slick, actually -
you could have a source deck of cards that you didn't change, and you stuck the
appropriate debugging 'AT' stuff on the end rather than have to insert code
with 'WRITE (6,*) N,I,FOO' where you wanted it. Incredibly useful if you were
doing debugging with an IBM 029 card punch and a fat deck of source code... ;)
[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-14 16:01 ` Luke Kenneth Casson Leighton
2005-03-14 19:27 ` Valdis.Kletnieks
@ 2005-03-14 20:10 ` Stephen Smalley
1 sibling, 0 replies; 58+ messages in thread
From: Stephen Smalley @ 2005-03-14 20:10 UTC (permalink / raw)
To: Luke Kenneth Casson Leighton; +Cc: KaiGai Kohei, SELinux Mail List, kaigai
On Mon, 2005-03-14 at 16:01 +0000, Luke Kenneth Casson Leighton wrote:
> what is the one significant distinct advantage that the proposed
> inheritance thing gives you that macro refactoring cannot?
Direct expression of certain type relationships in the language would
allow tools to manipulate such relationships without having to deal with
the much less constrained world of m4 macros. I can understand that
desire; I just want to make sure that it is done in a way that will be
practically useful. The not-yet-merged binary policy modules support
has no way today to deal with e.g. instantiation of program domains for
each user role/domain.
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-14 16:38 ` Karl MacMillan
@ 2005-03-15 11:47 ` KaiGai Kohei
2005-03-15 14:00 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: KaiGai Kohei @ 2005-03-15 11:47 UTC (permalink / raw)
To: Karl MacMillan; +Cc: 'SELinux Mail List', kaigai, selinux-dev
Hi Karl, Thanks for your comments.
>> Interesting patch and I'm glad to see you use sediff for testing this - it has
>> proven very valuable to use when doing work on checkpolicy for us as well. My
>> concern for this (in addition to Steve's comments) is that it isn't general
>> enough to solve many of the policy language problems that we commonly see. For
>> example, this doesn't help with types that are derived on a per-role basis. This
>> is a conceptually similar problem - I want user_ssh_t to be very similar
>> staff_ssh_t with some differences - but requires some additional features. I am
>> interested in extending this because right now it is not possible to easily add
>> roles to binary policies, like the modules, because the per-role types are not
>> correctly created.
In my understanding, your concern is that child type/domain always inherit
parent's attachments of roles, and this character make it hard to define
similar type/domain which belong to different roles.
It can be resolved by multi-layer type/domain inheritance.
e.g)
type generic_ssh_t;
type user_ssh_t extends generic_ssh_t;
type staff_ssh_t extends generic_ssh_t;
generic_ssh_t is attached some generic and necessary permissions and attributes,
but generic_ssh_t does not belong to any roles.
user_ssh_t and staff_ssh_t is defined as a child type of generic_ssh_t.
Those are attached specific permissions and attributes, and each type belong to
own roles.
This look like the usage of ATTRIBUTE. But we can't define multi-layer structure
for attribute on current checkpolicy. My extension make it possible.
>> I don't have a concrete suggestion, but an example would be a policy syntax that
>> could duplicate the ssh_domain macro. Instead of creating a type based on
>> another type, it would be creating a type based on a 'type template'. This would
>> allow creating user_ssh_t and staff_ssh_t, for example, with similar access in
>> many cases, but also differences (e.g., user_home_ssh_t and staff_home_ssh_t or
>> a different transition from ssh_exec_t).
Indeed, we can also define such types by 'type template' macros, I think.
But I wonder whether type configuration by multiple macros is enough easy
for general end-user or not.
My original motivation willing to implement TYPE ... EXTENDS is that
making it easier to define original type/domain by using an existing
correct type/domain definition, because defining a new type/domain from
scratch is required so wide knowledge for application, kernel, SELinux and macros.
(Education often requires massive cost.)
In many case, an imitation of existing type/domain is easier than
to enforce end-user learning about application, kernel, SELinux and macros.
Thanks.
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-14 18:25 ` Stephen Smalley
@ 2005-03-15 11:50 ` KaiGai Kohei
2005-03-15 14:42 ` Stephen Smalley
2005-04-06 12:49 ` Russell Coker
0 siblings, 2 replies; 58+ messages in thread
From: KaiGai Kohei @ 2005-03-15 11:50 UTC (permalink / raw)
To: Stephen Smalley; +Cc: SELinux Mail List, kaigai
Hi Stephen, Thanks for your comments.
>> This makes sense for unifying file types, as in the earlier multiple
>> contexts thread. I'm not sure I see how it is useful for domains; any
>> permissions allowed to the child domain can be indirectly gained by the
>> parent domain (or any domain which can control the parent domain) and
>> any program executables that can be used to enter the parent domain can
>> be used to enter the child domain, so you might as well just directly
>> allow the permissions to the parent domain. As a trivial example, if
>> you declare 'type user_ext_t extends user_t;', then user_t gets ptrace
>> permission to user_ext_t because it has ptrace permission to itself, so
>> any user_t process has full control over user_ext_t and can thus
>> exercise its permissions at will.
Does 'unifying file type' means as follows ?
e.g)
/var ... var_t
/var/lib ... var_lib_t extends var_t
/var/log ... var_log_t extends var_t
/var/log/message ... var_log_message_t extends var_log_t
Of course, such a usage is also possible.
In user_t/user_ext_t example, user_ext_t is same as user_t without tiny difference.
Thus, it is strange, if user_t process which has a permission to user_t does not
have a same permission to user_ext_t.
Common part of user_t and user_ext_t should have a permission for each other, I think.
The outbounds part of user_ext_t from user_t should not have a permission
for each other, indeed.
>>>>I think definition of reductive permission child-type/domain is the next
>>>>action assignment. If child does not need a part of the parent's permissions,
>>>>those should be revoked by DENY statement for example.
>
>>
>>
>> Hmmm...given the way in which you are computing inheritance, it seems
>> that it could be very easy to miss something being implicitly allowed
>> and fail to define a corresponding deny statement. Maintainability also
>> becomes a problem as you have to reassess the deny rules whenever a new
>> allow rule is added. And we need to consider not only limiting the
>> child, but limiting the parent from controlling the child, if we are
>> going to allow more permissions to the child than the parent.
I want to reserve this matter once for a certain time.
Because there is a problem as you notice, and I noticed the amount of modification
with DENY implementation is so large.
Sorry, I want to concentrate the discussion for TYPE ... EXTENDS first.
>>>>When child_t inherit parent_t, "allow parent_t parent_t:process sigkill;"
>>>>is unrolled to "allow {parent_t child_t} {parent_t child_t}:process sigkill;"
>>>>The number of conbination is 4.
>>>>
>>>>"allow parent_t self:process sigkill;" is unrolled as follows:
>>>> "allow parent_t parent_t:process sigkill;"
>>>> "allow parent_t child_t:process sigkill;"
>>>> "allow child_t child_t:process sigkill;"
>
>>
>>
>> The latter is more in line with what I would expect, and regardless, I
>> think that they should be unrolled consistently regardless of whether
>> the allow rule was written with "self" or explicitly with the same
>> domain (or an attribute that included the domain); self was purely
>> intended as a convenience notation and a way to express the self
>> relationship when using an attribute/set for the source type.
I see.
But I thought it may be unnaturalness that child_t doesn't have a permission to parent_t.
What you say first is straightforward explanation.
It's natual "allow parent_t self:..." is unrolled to
"allow {parent_t child_t} {parent_t child_t}:...", and I'll fix it.
>> Typically, when creating a derived domain (e.g. for a program run by a
>> user domain), we don't want to inherit any of the transition rules of
>> the base user domain. A template-based approach as suggested by Karl
>> seems necessary here, effectively turning the existing macro constructs
>> into a language feature.
In my implementation, derived domain inherit any of transition rules of
the own parent domain in default. If we don't want to apply same type
transition rules, we must define a different rules to derived domain
explicitly.
So, I can't decide whether this essence is advantage or disadvantage...
In addition, it's possible not to decide a transition type/domain
when a type has multiple parents. Should the number of parent
types/domains be limited to one ?
Thanks.
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-15 11:47 ` KaiGai Kohei
@ 2005-03-15 14:00 ` Karl MacMillan
2005-03-16 4:35 ` Kaigai Kohei
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2005-03-15 14:00 UTC (permalink / raw)
To: 'KaiGai Kohei'; +Cc: 'SELinux Mail List', kaigai, selinux-dev
> -----Original Message-----
> From: KaiGai Kohei [mailto:kaigai@kaigai.gr.jp]
> Sent: Tuesday, March 15, 2005 6:47 AM
> To: Karl MacMillan
> Cc: 'SELinux Mail List'; kaigai@ak.jp.nec.com; selinux-dev@tresys.com
> Subject: Re: [RFC & PATCH] inherited type definition.
>
> Hi Karl, Thanks for your comments.
>
> >> Interesting patch and I'm glad to see you use sediff for
> testing this - it has >> proven very valuable to use when
> doing work on checkpolicy for us as well. My >> concern for
> this (in addition to Steve's comments) is that it isn't
> general >> enough to solve many of the policy language
> problems that we commonly see. For >> example, this doesn't
> help with types that are derived on a per-role basis. This
> >> is a conceptually similar problem - I want user_ssh_t to
> be very similar >> staff_ssh_t with some differences - but
> requires some additional features. I am >> interested in
> extending this because right now it is not possible to easily
> add >> roles to binary policies, like the modules, because
> the per-role types are not >> correctly created.
>
> In my understanding, your concern is that child type/domain
> always inherit parent's attachments of roles, and this
> character make it hard to define similar type/domain which
> belong to different roles.
>
Not exactly - that is certainly one problem, but the main problem is that I want
the ability to create a group of types based on another group of types, e.g. I
want to create staff_ssh_t and staff_home_ssh_t based on the corresponding user
types. In this model staff_ssh_t wouldn't have any access to user_home_ssh_t,
instead it will have the same access that user_ssh_t has to user_home_ssh_t
except to staff_home_ssh_t.
> It can be resolved by multi-layer type/domain inheritance.
>
> e.g)
> type generic_ssh_t;
> type user_ssh_t extends generic_ssh_t;
> type staff_ssh_t extends generic_ssh_t;
>
> generic_ssh_t is attached some generic and necessary
> permissions and attributes, but generic_ssh_t does not belong
> to any roles.
> user_ssh_t and staff_ssh_t is defined as a child type of
> generic_ssh_t.
> Those are attached specific permissions and attributes, and
> each type belong to own roles.
>
This would define the shared access that staff_ssh_t and user_ssh_t have, but
doesn't address the related types that are needed (e.g., staff_home_ssh_t).
> This look like the usage of ATTRIBUTE. But we can't define
> multi-layer structure for attribute on current checkpolicy.
> My extension make it possible.
>
I'm not certain what you mean here - if generic_ssh was an attribute with a
defined set of permissions, this would work almost the same. The
user/staff_ssh_t would need some additional attributes in addition to
generic_ssh, but otherwise this is very similar. Can you explain the advantage
to your suggestion in more detail?
> >> I don't have a concrete suggestion, but an example would
> be a policy syntax that >> could duplicate the ssh_domain
> macro. Instead of creating a type based on >> another type,
> it would be creating a type based on a 'type template'. This
> would >> allow creating user_ssh_t and staff_ssh_t, for
> example, with similar access in >> many cases, but also
> differences (e.g., user_home_ssh_t and staff_home_ssh_t or
> >> a different transition from ssh_exec_t).
>
> Indeed, we can also define such types by 'type template'
> macros, I think.
> But I wonder whether type configuration by multiple macros is
> enough easy for general end-user or not.
I don't want to use macros because it requires source - I am looking for a
construct in the language that the binary modules can utilize. Obviously, for
the ssh example there would also need to be syntax that stated that this type
template should be instantiated for each role.
> My original motivation willing to implement TYPE ... EXTENDS
> is that making it easier to define original type/domain by
> using an existing correct type/domain definition, because
> defining a new type/domain from scratch is required so wide
> knowledge for application, kernel, SELinux and macros.
> (Education often requires massive cost.) In many case, an
> imitation of existing type/domain is easier than to enforce
> end-user learning about application, kernel, SELinux and macros.
>
It may be easier, but it is fundamentally dangerous. A user that simply extends
an existing type without understanding the access granted to that type is
potentially granting a new type excessive access. I think that there are real
capabilities that are needed in the language, but I disagree with adding this
syntax simply for ease-of-use. I think that there are other methods to make it
easier for users to author policy without these dangers.
Karl
---
Karl MacMillan
Tresys Technology
http://www.tresys.com
(410) 290-1411 ext 134
> Thanks.
> --
> DO NOTHING IS THE WORST POLICY.
> KaiGai Kohei <kaigai@kaigai.gr.jp>
>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-15 11:50 ` KaiGai Kohei
@ 2005-03-15 14:42 ` Stephen Smalley
2005-03-16 4:42 ` Kaigai Kohei
2005-04-06 12:49 ` Russell Coker
1 sibling, 1 reply; 58+ messages in thread
From: Stephen Smalley @ 2005-03-15 14:42 UTC (permalink / raw)
To: KaiGai Kohei; +Cc: SELinux Mail List, kaigai
On Tue, 2005-03-15 at 20:50 +0900, KaiGai Kohei wrote:
> Does 'unifying file type' means as follows ?
> e.g)
> /var ... var_t
> /var/lib ... var_lib_t extends var_t
> /var/log ... var_log_t extends var_t
> /var/log/message ... var_log_message_t extends var_log_t
> Of course, such a usage is also possible.
I was thinking more of an example like:
type samba_httpd_content_t extends samba_share_t, httpd_sys_content_t;
in order to create a union type that can be accessed by both samba and
httpd. See the earlier "multiple contexts" thread on this list.
> In user_t/user_ext_t example, user_ext_t is same as user_t without tiny difference.
> Thus, it is strange, if user_t process which has a permission to user_t does not
> have a same permission to user_ext_t.
But if user_ext_t has more permissions than user_t, then allowing user_t
to access user_ext_t in the same manner as it can access user_t means
that a user_t process can effectively gain control of those same
permissions too, just by transitioning to user_ext_t and running code in
it or by ptrace'ing or otherwise acting upon a separate user_ext_t
process. Thus, you gain nothing from having a separate user_ext_t
type; there is no real protection/separation between user_t and
user_ext_t, and you might as well directly allow the permissions to
user_t. Why create a new type if you gain no security benefit?
> Common part of user_t and user_ext_t should have a permission for each other, I think.
> The outbounds part of user_ext_t from user_t should not have a permission
> for each other, indeed.
I'm not sure how you distinguish the "common part" from the "outbounds
part". Is this a notion of "private" and "public" portions of a type
definition?
> I want to reserve this matter once for a certain time.
> Because there is a problem as you notice, and I noticed the amount of modification
> with DENY implementation is so large.
> Sorry, I want to concentrate the discussion for TYPE ... EXTENDS first.
Ok, but we still need a way to make the "type...extends" feature
practically useful by itself. As it stands, if you use it to define a
more privileged child than the parent, the parent can easily take
control of it and effectively gain those permissions too, so you might
as well directly allow the permissions to the parent and not create the
child at all. The only use it has in its current form is to create
union types.
> In addition, it's possible not to decide a transition type/domain
> when a type has multiple parents. Should the number of parent
> types/domains be limited to one ?
No, I think the multiple inheritance is useful, e.g. for the union file
type case. Possibly we need a way to mark which parent should be used
for inheriting type transitions.
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-15 14:00 ` Karl MacMillan
@ 2005-03-16 4:35 ` Kaigai Kohei
2005-03-16 10:13 ` Luke Kenneth Casson Leighton
2005-03-16 21:31 ` Karl MacMillan
0 siblings, 2 replies; 58+ messages in thread
From: Kaigai Kohei @ 2005-03-16 4:35 UTC (permalink / raw)
To: Karl MacMillan
Cc: 'KaiGai Kohei', 'SELinux Mail List', selinux-dev
Hi Karl, Thanks for your comments.
> Not exactly - that is certainly one problem, but the main problem is that I want
> the ability to create a group of types based on another group of types, e.g. I
> want to create staff_ssh_t and staff_home_ssh_t based on the corresponding user
> types. In this model staff_ssh_t wouldn't have any access to user_home_ssh_t,
> instead it will have the same access that user_ssh_t has to user_home_ssh_t
> except to staff_home_ssh_t.
OK, I have misunderstood about your concern.
BTW, I don't think your 'group of types' idea conflicts with my patch.
Because the results of "TYPE ... EXTENDS" look like two similar type/domain in binary level,
any existing tools can handle the generated policy binary without any problems.
(Thus, I adopted sediff to check the patched checkpolicy.)
How does your ideas work ? and, how does conflict with "TYPE ... EXTENDS" approach?
>>This look like the usage of ATTRIBUTE. But we can't define
>>multi-layer structure for attribute on current checkpolicy.
>>My extension make it possible.
>
> I'm not certain what you mean here - if generic_ssh was an attribute with a
> defined set of permissions, this would work almost the same. The
> user/staff_ssh_t would need some additional attributes in addition to
> generic_ssh, but otherwise this is very similar. Can you explain the advantage
> to your suggestion in more detail?
Yes, those works similarly. But current implementation of attribute doesn't
permit such a usage. In above example, generic_ssh is attached some attributes,
but we can't attach any attributed to attribute on current checkpolicy.
Because "TYPE ... EXTENDS" statement is implemented by existing attribute
implementation, this extension has similar functionality is natural.
This extensiton make it possible to define multiple-layer type/domain with
minimum modification and enough compatibility.
> It may be easier, but it is fundamentally dangerous. A user that simply extends
> an existing type without understanding the access granted to that type is
> potentially granting a new type excessive access. I think that there are real
> capabilities that are needed in the language, but I disagree with adding this
> syntax simply for ease-of-use. I think that there are other methods to make it
> easier for users to author policy without these dangers.
Since we can't enforce end-user to apply specific configuration, it's possible
to happen an excessive access in anywhere. I think end-user should select
the best way corresponding to own skill and so on.
Providing another options is not bad.
Thanks,
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-15 14:42 ` Stephen Smalley
@ 2005-03-16 4:42 ` Kaigai Kohei
2005-03-16 10:00 ` Luke Kenneth Casson Leighton
2005-03-16 14:05 ` Stephen Smalley
0 siblings, 2 replies; 58+ messages in thread
From: Kaigai Kohei @ 2005-03-16 4:42 UTC (permalink / raw)
To: Stephen Smalley; +Cc: KaiGai Kohei, SELinux Mail List
Hi Stephen, Thanks for your comments ?
> I was thinking more of an example like:
> type samba_httpd_content_t extends samba_share_t, httpd_sys_content_t;
> in order to create a union type that can be accessed by both samba and
> httpd. See the earlier "multiple contexts" thread on this list.
Indeed, this is interresting usage.
I'll try to re-read above thread earnestly.
>>In user_t/user_ext_t example, user_ext_t is same as user_t without tiny difference.
>>Thus, it is strange, if user_t process which has a permission to user_t does not
>>have a same permission to user_ext_t.
>
> But if user_ext_t has more permissions than user_t, then allowing user_t
> to access user_ext_t in the same manner as it can access user_t means
> that a user_t process can effectively gain control of those same
> permissions too, just by transitioning to user_ext_t and running code in
> it or by ptrace'ing or otherwise acting upon a separate user_ext_t
> process. Thus, you gain nothing from having a separate user_ext_t
> type; there is no real protection/separation between user_t and
> user_ext_t, and you might as well directly allow the permissions to
> user_t. Why create a new type if you gain no security benefit?
Indeed, a user_t process can take permissions of a user_ext_t process
through ptrace. It was blid spot for me.
I think, this has the cause in inheriting all of parent-permissions
unconditionally, not selective. Thus, there is no difference in between
user_ext_t and user_t essentially.
If we can resolve this matter, what we can define domain with EXTENDS
statement has worthiness in that we can use existing correct type as
a template to define a new type/domain.
I have an idea that ALLOW statement is added an new option
For example:
ALLOW @user_t @user_t:process {ptrace};
ALLOW user_t @user_t:process {transition};
When '@' is added in front of the type name, this means source/target
type is only user_t, not including user_ext_t and descendant.
Above example is rolled out as follows:
ALLOW user_t user_t:process {ptrace};
ALLOW {user_t user_ext_t}:process {transition};
It restrains unlimited inheritance of permissions to child type/domain.
Can this approach solve such a concern ?
>>In addition, it's possible not to decide a transition type/domain
>>when a type has multiple parents. Should the number of parent
>>types/domains be limited to one ?
>
> No, I think the multiple inheritance is useful, e.g. for the union file
> type case. Possibly we need a way to mark which parent should be used
> for inheriting type transitions.
I see. The multiple inheritance is indeed useful and interresting, I noticed.
So, does above '@' proposal make such a marking possible ?
Thanks.
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-16 4:42 ` Kaigai Kohei
@ 2005-03-16 10:00 ` Luke Kenneth Casson Leighton
2005-03-16 14:05 ` Stephen Smalley
1 sibling, 0 replies; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-16 10:00 UTC (permalink / raw)
To: Kaigai Kohei; +Cc: Stephen Smalley, KaiGai Kohei, SELinux Mail List
On Wed, Mar 16, 2005 at 01:42:56PM +0900, Kaigai Kohei wrote:
> I have an idea that ALLOW statement is added an new option
> For example:
> ALLOW @user_t @user_t:process {ptrace};
> ALLOW user_t @user_t:process {transition};
>
> When '@' is added in front of the type name, this means source/target
> type is only user_t, not including user_ext_t and descendant.
> Above example is rolled out as follows:
> ALLOW user_t user_t:process {ptrace};
> ALLOW {user_t user_ext_t}:process {transition};
that i like.
an "after-the-fact" scheme i don't [one where you inherit and then
specify what you _don't_ want to be included].
an explicit marker on parent rules saying "you can't inherit this"
i like.
i like best the one which explicity says "all these rules within these
curly braces are inheritable".
positive statements, the default being "nothing is inheritable",
matches up better with the "mandatory access control" methodology.
no assumptions. nothing granted by mistake. always explicitly say
what's allowed.
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-16 4:35 ` Kaigai Kohei
@ 2005-03-16 10:13 ` Luke Kenneth Casson Leighton
2005-03-16 21:46 ` Karl MacMillan
2005-03-16 21:31 ` Karl MacMillan
1 sibling, 1 reply; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-16 10:13 UTC (permalink / raw)
To: Kaigai Kohei
Cc: Karl MacMillan, 'KaiGai Kohei',
'SELinux Mail List', selinux-dev
On Wed, Mar 16, 2005 at 01:35:36PM +0900, Kaigai Kohei wrote:
> Hi Karl, Thanks for your comments.
>
> > Not exactly - that is certainly one problem, but the main problem is that I want
> > the ability to create a group of types based on another group of types, e.g. I
> > want to create staff_ssh_t and staff_home_ssh_t based on the corresponding user
> > types. In this model staff_ssh_t wouldn't have any access to user_home_ssh_t,
> > instead it will have the same access that user_ssh_t has to user_home_ssh_t
> > except to staff_home_ssh_t.
>
oh _drat_.
you might be running into almost exactly the same stupid
pre-processor issues i ran into in gcc with c++ (if you pre-process,
how can you use c++ templates on macro-pre-processed code???)
*thinks some more*.
karl, could you elaborate with an example?
if you put the inheritance statement into the macro, such that it gets
expanded out, why is there a problem?
$1_t extends $1_something_t
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-16 4:42 ` Kaigai Kohei
2005-03-16 10:00 ` Luke Kenneth Casson Leighton
@ 2005-03-16 14:05 ` Stephen Smalley
2005-03-17 9:32 ` Kaigai Kohei
1 sibling, 1 reply; 58+ messages in thread
From: Stephen Smalley @ 2005-03-16 14:05 UTC (permalink / raw)
To: Kaigai Kohei; +Cc: KaiGai Kohei, SELinux Mail List
On Wed, 2005-03-16 at 13:42 +0900, Kaigai Kohei wrote:
> I have an idea that ALLOW statement is added an new option
> For example:
> ALLOW @user_t @user_t:process {ptrace};
> ALLOW user_t @user_t:process {transition};
>
> When '@' is added in front of the type name, this means source/target
> type is only user_t, not including user_ext_t and descendant.
> Above example is rolled out as follows:
> ALLOW user_t user_t:process {ptrace};
> ALLOW {user_t user_ext_t}:process {transition};
>
> It restrains unlimited inheritance of permissions to child type/domain.
> Can this approach solve such a concern ?
Note that at least in this case, even the ability to transition prevents
any real separation between user_t and user_ext_t, because user_t and
user_ext_t can be entered by a shell, so with transition permission,
user_t can then run a shell in user_ext_t and perform arbitrary actions
with those permissions.
One obvious question is how @<attributename> would be interpreted;
offhand, I would expect it to prevent expansion of the descendants of
the individual types that have the attribute. One concern with this
approach is that you have to explicitly mark types in order to prevent
expansion rather than having to explicitly mark types that you want to
expand, which seems prone to accidental expansion. Note that we have to
consider not only rules that directly specify the type but rules that
may indirectly include the type via attribute or set complement (~).
Requiring explicit marking of types to allow expansion of descendants
would presumably require more work by someone who wants to extend a
type, but would avoid unintentional expansion.
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-16 4:35 ` Kaigai Kohei
2005-03-16 10:13 ` Luke Kenneth Casson Leighton
@ 2005-03-16 21:31 ` Karl MacMillan
2005-03-17 13:05 ` Kaigai Kohei
1 sibling, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2005-03-16 21:31 UTC (permalink / raw)
To: 'Kaigai Kohei'
Cc: 'KaiGai Kohei', 'SELinux Mail List', selinux-dev
> -----Original Message-----
> From: Kaigai Kohei [mailto:kaigai@ak.jp.nec.com]
> Sent: Tuesday, March 15, 2005 11:36 PM
> To: Karl MacMillan
> Cc: 'KaiGai Kohei'; 'SELinux Mail List'; selinux-dev@tresys.com
> Subject: Re: [RFC & PATCH] inherited type definition.
>
> Hi Karl, Thanks for your comments.
>
> > Not exactly - that is certainly one problem, but the main
> problem is
> > that I want the ability to create a group of types based on another
> > group of types, e.g. I want to create staff_ssh_t and
> staff_home_ssh_t
> > based on the corresponding user types. In this model staff_ssh_t
> > wouldn't have any access to user_home_ssh_t, instead it
> will have the
> > same access that user_ssh_t has to user_home_ssh_t except
> to staff_home_ssh_t.
>
> OK, I have misunderstood about your concern.
>
> BTW, I don't think your 'group of types' idea conflicts with my patch.
> Because the results of "TYPE ... EXTENDS" look like two
> similar type/domain in binary level, any existing tools can
> handle the generated policy binary without any problems.
> (Thus, I adopted sediff to check the patched checkpolicy.)
> How does your ideas work ? and, how does conflict with "TYPE
> ... EXTENDS" approach?
>
I'm not certain that you understand my objection. I'm not suggesting that your
patch conflicts with this idea, I think that we should not make this type of
language change unless it address a broad set of issues, which to me includes
this group of types usage scenario. The EXTENDS syntax seems, to me, to have a
fairly narrow usage similar to clone rules. The clone rules were ultimately
dropped so I don't think that we should go down that path again without major
additional advantages. In other words, I saying that I think handling the group
of types usage scenario is a requirement to this type of language extension.
>
> >>This look like the usage of ATTRIBUTE. But we can't define
> multi-layer
> >>structure for attribute on current checkpolicy.
> >>My extension make it possible.
> >
> > I'm not certain what you mean here - if generic_ssh was an
> attribute
> > with a defined set of permissions, this would work almost the same.
> > The user/staff_ssh_t would need some additional attributes
> in addition
> > to generic_ssh, but otherwise this is very similar. Can you explain
> > the advantage to your suggestion in more detail?
>
> Yes, those works similarly. But current implementation of
> attribute doesn't permit such a usage. In above example,
> generic_ssh is attached some attributes, but we can't attach
> any attributed to attribute on current checkpolicy.
> Because "TYPE ... EXTENDS" statement is implemented by
> existing attribute implementation, this extension has similar
> functionality is natural.
> This extensiton make it possible to define multiple-layer
> type/domain with minimum modification and enough compatibility.
>
As I stated above, my example requires the attributes to be applied to
user/staff_ssh_t. This to me does not seem to be a major drawback - in fact it
gives more control to the policy author.
> > It may be easier, but it is fundamentally dangerous. A user that
> > simply extends an existing type without understanding the access
> > granted to that type is potentially granting a new type excessive
> > access. I think that there are real capabilities that are needed in
> > the language, but I disagree with adding this syntax simply for
> > ease-of-use. I think that there are other methods to make
> it easier for users to author policy without these dangers.
>
> Since we can't enforce end-user to apply specific
> configuration, it's possible to happen an excessive access in
> anywhere. I think end-user should select the best way
> corresponding to own skill and so on.
> Providing another options is not bad.
>
Of course the current policy syntax allows the granting of excessive privilege,
but it avoids making it easy. The EXTENDS syntax has the same pitfall that
"allow foo ~bar : . . ." or the granting of broad access to attributes has - the
policy author ultimately grants access implicitly rather than explicitly. I
think that we should avoid that pitfall. Again, I am not against making it
easier for policy authors to write correct policy, I am just concerned that this
syntax is not the best option.
Karl
---
Karl MacMillan
Tresys Technology
http://www.tresys.com
(410) 290-1411 ext 134
> Thanks,
> --
> DO NOTHING IS THE WORST POLICY.
> KaiGai Kohei <kaigai@kaigai.gr.jp>
>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-16 10:13 ` Luke Kenneth Casson Leighton
@ 2005-03-16 21:46 ` Karl MacMillan
0 siblings, 0 replies; 58+ messages in thread
From: Karl MacMillan @ 2005-03-16 21:46 UTC (permalink / raw)
To: 'Luke Kenneth Casson Leighton', 'Kaigai Kohei'
Cc: 'KaiGai Kohei', 'SELinux Mail List', selinux-dev
> -----Original Message-----
> From: Luke Kenneth Casson Leighton [mailto:lkcl@lkcl.net]
> Sent: Wednesday, March 16, 2005 5:14 AM
> To: Kaigai Kohei
> Cc: Karl MacMillan; 'KaiGai Kohei'; 'SELinux Mail List';
> selinux-dev@tresys.com
> Subject: Re: [RFC & PATCH] inherited type definition.
>
> On Wed, Mar 16, 2005 at 01:35:36PM +0900, Kaigai Kohei wrote:
> > Hi Karl, Thanks for your comments.
> >
> > > Not exactly - that is certainly one problem, but the main
> problem is
> > > that I want the ability to create a group of types based
> on another
> > > group of types, e.g. I want to create staff_ssh_t and
> > > staff_home_ssh_t based on the corresponding user types. In this
> > > model staff_ssh_t wouldn't have any access to user_home_ssh_t,
> > > instead it will have the same access that user_ssh_t has
> to user_home_ssh_t except to staff_home_ssh_t.
> >
>
> oh _drat_.
>
> you might be running into almost exactly the same stupid
> pre-processor issues i ran into in gcc with c++ (if you
> pre-process, how can you use c++ templates on
> macro-pre-processed code???)
>
>
> *thinks some more*.
>
> karl, could you elaborate with an example?
>
> if you put the inheritance statement into the macro, such
> that it gets expanded out, why is there a problem?
>
I am looking for a semantic that is part of the binary format - putting it in a
macro makes it happen at compile time and therefore isn't useful for production
systems without source.
> $1_t extends $1_something_t
>
'staff_ssh_t extends user_ssh_t'?
Again, I don't want to give staff_ssh_t access to user_home_ssh_t which the
above statement would, I want to give staff_ssh_t access to staff_home_ssh_t. I
want to pattern the access between two or more types on the access of two or
more types.
More generally, I want to be able to define an access template that can be
expanded in the binary policy so that, for example, adding a role will create
the appropriate set of types with the correct relationship.
In a lot of ways, this is moving a subset of the macro language into the binary
format with some additional syntax to say expand this macro for this type, type
prefix, all roles, etc. This could also be used to address the same things that
the EXTEND syntax does with more control and flexibility, though it would
require changes to the existing policy similar to converting a policy into
macros (the passwd_t, groupadd_t, etc macro is a good example).
Karl
> l.
>
---
Karl MacMillan
Tresys Technology
http://www.tresys.com
(410) 290-1411 ext 134
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-16 14:05 ` Stephen Smalley
@ 2005-03-17 9:32 ` Kaigai Kohei
2005-03-17 13:55 ` Stephen Smalley
0 siblings, 1 reply; 58+ messages in thread
From: Kaigai Kohei @ 2005-03-17 9:32 UTC (permalink / raw)
To: Stephen Smalley; +Cc: KaiGai Kohei, SELinux Mail List
Hi,
>>I have an idea that ALLOW statement is added an new option
>>For example:
>> ALLOW @user_t @user_t:process {ptrace};
>> ALLOW user_t @user_t:process {transition};
>>
>>When '@' is added in front of the type name, this means source/target
>>type is only user_t, not including user_ext_t and descendant.
>>Above example is rolled out as follows:
>> ALLOW user_t user_t:process {ptrace};
>> ALLOW {user_t user_ext_t}:process {transition};
>>
>>It restrains unlimited inheritance of permissions to child type/domain.
>>Can this approach solve such a concern ?
>
>
> Note that at least in this case, even the ability to transition prevents
> any real separation between user_t and user_ext_t, because user_t and
> user_ext_t can be entered by a shell, so with transition permission,
> user_t can then run a shell in user_ext_t and perform arbitrary actions
> with those permissions.
I agree, two-way transition permissions make the separation between each domains
meaningless. The '@' should be append in front of typenames as a general rule,
when we will attach ptrace, transition and dyntransition permissions.
I think can_ptrace() and domain_trans() macros should be modify to avoid
such a vague border of domain. Other grants of such permissions are similar.
> One obvious question is how @<attributename> would be interpreted;
> offhand, I would expect it to prevent expansion of the descendants of
> the individual types that have the attribute.
I intend that '@'<type/attribute name> is interpreted as if those
type/attribute is interpreted on current version checkpolicy(1.22).
In other word, '@'<typename> is merely recognized as <typename>,
any descendants are not included. '@'<attribute> is rolled out
some child types attached this attribute directly, not include
any indirect descendants.
e.g.
attribute attr;
type X;
type Y extends attr;
type Z extends Y;
"allow @attr foo:XXX XXX;" means "allow Y foo:XXX XXX;", Z is not included.
"allow @X foo:XXX XXX;" means "X foo:XXX XXX;", Y and Z is not included.
If you remove '@' from above statements, this action is same as current checkpolicy works.
> One concern with this
> approach is that you have to explicitly mark types in order to prevent
> expansion rather than having to explicitly mark types that you want to
> expand, which seems prone to accidental expansion.
To decide which is it preferable is a difficult issue.
My preference is that explicitly mark types means deny of expand, and
any permissions without above 3-operations should be expandable in default.
Effective use of existing software assets is reason.
For example, samba_httpd_content_t is a type extends samba_share_t
and httpd_sys_content_t. When we try to use the union filetype
"samba_httpd_content_t", we must fix the allow statements of "samba_share_t"
and "httpd_sys_content_t" if an allow statement without '@' means
no-expandable permission grant.
> Note that we have to
> consider not only rules that directly specify the type but rules that
> may indirectly include the type via attribute or set complement (~).
> Requiring explicit marking of types to allow expansion of descendants
> would presumably require more work by someone who wants to extend a
> type, but would avoid unintentional expansion.
OK, I'll fix up the latest patch with your notion.
Please wait for a while.
Thanks,
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-16 21:31 ` Karl MacMillan
@ 2005-03-17 13:05 ` Kaigai Kohei
2005-03-17 19:15 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Kaigai Kohei @ 2005-03-17 13:05 UTC (permalink / raw)
To: Karl MacMillan
Cc: 'KaiGai Kohei', 'SELinux Mail List', selinux-dev
Hello,
> I'm not certain that you understand my objection. I'm not suggesting that your
> patch conflicts with this idea, I think that we should not make this type of
> language change unless it address a broad set of issues, which to me includes
> this group of types usage scenario. The EXTENDS syntax seems, to me, to have a
> fairly narrow usage similar to clone rules. The clone rules were ultimately
> dropped so I don't think that we should go down that path again without major
> additional advantages. In other words, I saying that I think handling the group
> of types usage scenario is a requirement to this type of language extension.
There are some difference between the EXTENDS syntax and CLONE.
First, CLONE can't emulate multiple-parents inheritance. This is useful and
interresting character. Second, CLONE doesn't have a selective permission
grant syntax. I'm willing to implement selective permission grant syntax
such as '@' prefix.
What CLONE was dropped is not appropriate for the reason of this issue.
I feel this discussion fall into "discussion for discussion", so it's not
productive. You should make your target image clear, and express your modeling.
I can't compare practical functionality with vague images.
> As I stated above, my example requires the attributes to be applied to
> user/staff_ssh_t. This to me does not seem to be a major drawback - in fact it
> gives more control to the policy author.
Needless to say, the EXTENDS syntax does not prevent to apply any attributes.
In addition, your approach may be harmless, but opportunity benefit
as union-filetype will be lost if EXTENDS syntax is denied.
BTW, If we can control the access permission between 'group of type' and
union-filetype, it may be so flexible.
i.e. "Right man in the right place"
Thanks,
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-17 9:32 ` Kaigai Kohei
@ 2005-03-17 13:55 ` Stephen Smalley
2005-03-17 14:57 ` KaiGai Kohei
0 siblings, 1 reply; 58+ messages in thread
From: Stephen Smalley @ 2005-03-17 13:55 UTC (permalink / raw)
To: Kaigai Kohei; +Cc: KaiGai Kohei, SELinux Mail List
On Thu, 2005-03-17 at 18:32 +0900, Kaigai Kohei wrote:
> I intend that '@'<type/attribute name> is interpreted as if those
> type/attribute is interpreted on current version checkpolicy(1.22).
> In other word, '@'<typename> is merely recognized as <typename>,
> any descendants are not included. '@'<attribute> is rolled out
> some child types attached this attribute directly, not include
> any indirect descendants.
Yes, that is what I would expect.
> e.g.
> attribute attr;
> type X;
> type Y extends attr;
> type Z extends Y;
>
> "allow @attr foo:XXX XXX;" means "allow Y foo:XXX XXX;", Z is not included.
Ah, the fact that Y is included is interesting; this is due to the fact
that your implementation handles 'type Y extends attr;' in the same
manner as a 'type Y, attr;' declaration, right?
> Effective use of existing software assets is reason.
> For example, samba_httpd_content_t is a type extends samba_share_t
> and httpd_sys_content_t. When we try to use the union filetype
> "samba_httpd_content_t", we must fix the allow statements of "samba_share_t"
> and "httpd_sys_content_t" if an allow statement without '@' means
> no-expandable permission grant.
True, and you also have to track down all indirect references, e.g. uses
of "file_type" or "sysadmfile" in the policy.
> > Note that we have to
> > consider not only rules that directly specify the type but rules that
> > may indirectly include the type via attribute or set complement (~).
> > Requiring explicit marking of types to allow expansion of descendants
> > would presumably require more work by someone who wants to extend a
> > type, but would avoid unintentional expansion.
>
> OK, I'll fix up the latest patch with your notion.
> Please wait for a while.
Sorry, does this mean that you are going to change your implementation
to require explicit marking of types to allow expansion of descendants
(i.e. no expansion by default, and "@type" means expand descendants), or
not?
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-17 13:55 ` Stephen Smalley
@ 2005-03-17 14:57 ` KaiGai Kohei
2005-03-21 10:07 ` KaiGai Kohei
0 siblings, 1 reply; 58+ messages in thread
From: KaiGai Kohei @ 2005-03-17 14:57 UTC (permalink / raw)
To: Stephen Smalley; +Cc: Kaigai Kohei, SELinux Mail List
Hi,
>>e.g.
>>attribute attr;
>>type X;
>>type Y extends attr;
>>type Z extends Y;
>>
>>"allow @attr foo:XXX XXX;" means "allow Y foo:XXX XXX;", Z is not included.
>
>
> Ah, the fact that Y is included is interesting; this is due to the fact
> that your implementation handles 'type Y extends attr;' in the same
> manner as a 'type Y, attr;' declaration, right?
Yes, this EXTENDS syntax does not discriminate type with attribute.
There is no reason for dealing with those discriminatory, I think.
>>Effective use of existing software assets is reason.
>>For example, samba_httpd_content_t is a type extends samba_share_t
>>and httpd_sys_content_t. When we try to use the union filetype
>>"samba_httpd_content_t", we must fix the allow statements of "samba_share_t"
>>and "httpd_sys_content_t" if an allow statement without '@' means
>>no-expandable permission grant.
>
>
> True, and you also have to track down all indirect references, e.g. uses
> of "file_type" or "sysadmfile" in the policy.
Hmm,,,
Indeed, difficulty for validation has possibility to become complex problem.
OK, I'll implement EXTENDS patch with no-expansion by default and "@type" means
expand descendants.
I try to optimize that existing policy will be made EXTENDS syntax conscious.
Please wait new patch for a while.
Thanks
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-17 13:05 ` Kaigai Kohei
@ 2005-03-17 19:15 ` Karl MacMillan
2005-03-17 20:07 ` Stephen Smalley
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2005-03-17 19:15 UTC (permalink / raw)
To: 'Kaigai Kohei'
Cc: 'KaiGai Kohei', 'SELinux Mail List', selinux-dev
> -----Original Message-----
> From: Kaigai Kohei [mailto:kaigai@ak.jp.nec.com]
> Sent: Thursday, March 17, 2005 8:06 AM
> To: Karl MacMillan
> Cc: 'KaiGai Kohei'; 'SELinux Mail List'; selinux-dev@tresys.com
> Subject: Re: [RFC & PATCH] inherited type definition.
>
> Hello,
>
> > I'm not certain that you understand my objection. I'm not
> suggesting that your > patch conflicts with this idea, I
> think that we should not make this type of > language change
> unless it address a broad set of issues, which to me includes
> > this group of types usage scenario. The EXTENDS syntax
> seems, to me, to have a > fairly narrow usage similar to
> clone rules. The clone rules were ultimately > dropped so I
> don't think that we should go down that path again without
> major > additional advantages. In other words, I saying that
> I think handling the group > of types usage scenario is a
> requirement to this type of language extension.
>
> There are some difference between the EXTENDS syntax and CLONE.
> First, CLONE can't emulate multiple-parents inheritance. This
> is useful and interresting character. Second, CLONE doesn't
> have a selective permission grant syntax. I'm willing to
> implement selective permission grant syntax such as '@' prefix.
> What CLONE was dropped is not appropriate for the reason of
> this issue.
>
> I feel this discussion fall into "discussion for discussion",
> so it's not productive. You should make your target image
> clear, and express your modeling.
> I can't compare practical functionality with vague images.
>
This is a valid criticism - I don't have a concrete suggestion for my
requirements and I'll stop pushing it until I or someone else comes up with a
solution. I do, however, have a concrete alternative to this patch. After
thinking about this for a while, I think that the best alternative to this patch
right now is macros and simple copying of policy.
One of the stated uses for this patch is to allow naïve users to create a policy
based on an existing correct policy. Leaving aside whether it is a good idea for
naïve users to write straight SELinux policy, the problem with the extends
syntax is that it only allows for the creation of a superset of one or more
existing types (I guess that it can also create a copy, but then there would be
no reason for a new type). I assert that in most cases the creation of a new
policy that is similar to an existing policy will not result in this clean
superset. It is much easier to simply copy the existing .te file, run search and
replace to change the type names, and tweak as necessary.
The other uses for this syntax that I have seen suggested is to ease the
creation of two or more types that have a similar base set of permissions. I
think that macros address this use case well now and could be improved in the
future. The base_passwd_domain macro provides an example of how this is done. I
think that this is more understandable and easier to analyze than the extends
syntax, especially because the extends semantic is subtle (it has resulted in
considerable debate and it is still not clear exactly what is allowed and what
is not). With the extends syntax the entire policy must be examined to
understand what a type declaration actually allows if it includes an extend
statement. Macros are not perfect, but there is some hope that a single macro
(or a handful if it chains) is all that will have to be examined to have a
reasonable understanding of the allowed access resulting from a macro call.
Discipline in macro writing can make this situation even better.
I think that it is better to only add policy syntax when it solves a problem
that cannot be currently solved.
Karl
---
Karl MacMillan
Tresys Technology
http://www.tresys.com
(410) 290-1411 ext 134
> > As I stated above, my example requires the attributes to
> be applied to > user/staff_ssh_t. This to me does not seem
> to be a major drawback - in fact it > gives more control to
> the policy author.
>
> Needless to say, the EXTENDS syntax does not prevent to apply
> any attributes.
> In addition, your approach may be harmless, but opportunity
> benefit as union-filetype will be lost if EXTENDS syntax is denied.
>
> BTW, If we can control the access permission between 'group
> of type' and union-filetype, it may be so flexible.
> i.e. "Right man in the right place"
>
> Thanks,
> --
> DO NOTHING IS THE WORST POLICY.
> KaiGai Kohei <kaigai@kaigai.gr.jp>
>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-17 19:15 ` Karl MacMillan
@ 2005-03-17 20:07 ` Stephen Smalley
2005-03-17 21:41 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Stephen Smalley @ 2005-03-17 20:07 UTC (permalink / raw)
To: Karl MacMillan
Cc: 'Kaigai Kohei', 'KaiGai Kohei',
'SELinux Mail List', selinux-dev
On Thu, 2005-03-17 at 14:15 -0500, Karl MacMillan wrote:
> I do, however, have a concrete alternative to this patch. After
> thinking about this for a while, I think that the best alternative to this patch
> right now is macros and simple copying of policy.
Hmm...I wouldn't quite expect such a statement from the creators of
conditional policy support and binary policy modules ;)
> One of the stated uses for this patch is to allow naïve users to create a policy
> based on an existing correct policy. Leaving aside whether it is a good idea for
> naïve users to write straight SELinux policy, the problem with the extends
> syntax is that it only allows for the creation of a superset of one or more
> existing types (I guess that it can also create a copy, but then there would be
> no reason for a new type).
It would allow easy expression of union types, per the earlier
discussion in the thread on multiple contexts (but in a way that is
analyzable based on policy rather than filesystem state).
> With the extends syntax the entire policy must be examined to
> understand what a type declaration actually allows if it includes an extend
> statement.
This isn't fundamentally different from type attributes, particularly as
the patch is implemented as a minor refinement on attributes. In
effect, every type becomes an implicitly defined attribute that expands
to itself and any descendants. And if KaiGai does change the patch to
require use of the @ prefix to explicitly cause expansion of the type,
with no expansion by default, it seems fairly straightforward to
identify all relevant rules that might be affected by an extends
declaration. Other important point is that it has no impact on the
binary policy representation, so analysis based on binary policy remains
unchanged.
> Macros are not perfect, but there is some hope that a single macro
> (or a handful if it chains) is all that will have to be examined to have a
> reasonable understanding of the allowed access resulting from a macro call.
> Discipline in macro writing can make this situation even better.
Attributes, set difference, and set complement make this problematic
already, right?
> I think that it is better to only add policy syntax when it solves a problem
> that cannot be currently solved.
There is presently no way to easily express a union of multiple types.
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-17 20:07 ` Stephen Smalley
@ 2005-03-17 21:41 ` Karl MacMillan
2005-03-18 13:13 ` Stephen Smalley
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2005-03-17 21:41 UTC (permalink / raw)
To: 'Stephen Smalley'
Cc: 'Kaigai Kohei', 'KaiGai Kohei',
'SELinux Mail List', selinux-dev
> -----Original Message-----
> From: Stephen Smalley [mailto:sds@tycho.nsa.gov]
> Sent: Thursday, March 17, 2005 3:08 PM
> To: Karl MacMillan
> Cc: 'Kaigai Kohei'; 'KaiGai Kohei'; 'SELinux Mail List';
> selinux-dev@tresys.com
> Subject: RE: [RFC & PATCH] inherited type definition.
>
> On Thu, 2005-03-17 at 14:15 -0500, Karl MacMillan wrote:
> > I do, however, have a concrete alternative to this patch. After
> > thinking about this for a while, I think that the best
> alternative to
> > this patch right now is macros and simple copying of policy.
>
> Hmm...I wouldn't quite expect such a statement from the
> creators of conditional policy support and binary policy modules ;)
>
I know - I was hoping no one would notice. Seriously, I think that some things
are better done as part of the development environment. Additionally, I think
that the policy needs some better abstractions at the source level and that will
address some of these issues - see below.
> > One of the stated uses for this patch is to allow naïve users to
> > create a policy based on an existing correct policy. Leaving aside
> > whether it is a good idea for naïve users to write straight SELinux
> > policy, the problem with the extends syntax is that it only
> allows for
> > the creation of a superset of one or more existing types (I
> guess that
> > it can also create a copy, but then there would be no
> reason for a new type).
>
> It would allow easy expression of union types, per the
> earlier discussion in the thread on multiple contexts (but in
> a way that is analyzable based on policy rather than
> filesystem state).
>
That's correct, but I argue that a complete union is seldom what is wanted. More
often we want a partial union, which is what the @ syntax is supposed to
express. I think, however, that macros can express this more directly and
readably.
> > With the extends syntax the entire policy must be examined to
> > understand what a type declaration actually allows if it
> includes an
> > extend statement.
>
> This isn't fundamentally different from type attributes,
> particularly as the patch is implemented as a minor
> refinement on attributes.
Sure, and I think that attributes are somewhat evil as well. Again, my
experience trying to understand policies leads me to say that more of the policy
that can be expressed directly through allow rules on types the better.
Automated analysis can unwind these indirections, but there is still significant
advantages to being able to understand source policies.
> In effect, every type becomes an
> implicitly defined attribute that expands to itself and any
> descendants. And if KaiGai does change the patch to require
> use of the @ prefix to explicitly cause expansion of the
> type, with no expansion by default, it seems fairly
> straightforward to identify all relevant rules that might be
> affected by an extends declaration.
If this change does happen I hope that the @ prefix will be required to cause
expansion. At this point, though, the amount of work required to change the
policy to use the @ where needed is on the same order as abstracting these types
into macros, and I think there would be additional benefits from the macro
abstraction that the @ markup does not have.
> Other important point is
> that it has no impact on the binary policy representation, so
> analysis based on binary policy remains unchanged.
>
Certainly, but it is potentially an impact on source policy readability.
> > Macros are not perfect, but there is some hope that a single macro
> > (or a handful if it chains) is all that will have to be examined to
> > have a reasonable understanding of the allowed access
> resulting from a macro call.
> > Discipline in macro writing can make this situation even better.
>
> Attributes, set difference, and set complement make this
> problematic already, right?
>
Yes - and I have already complained about those in another email. I'll be happy
to send a patch disallowing complement in allow rules if you would accept it :)
> > I think that it is better to only add policy syntax when it
> solves a
> > problem that cannot be currently solved.
>
> There is presently no way to easily express a union of multiple types.
>
I disagree - macros allow this. Also, what we want, I think, is not a union of
types but an abstract notion of access. Your earlier example of
samba_http_content_t is better expressed through:
allow_samba_read(foo_t)
allow_httpd_read(foo_t)
This is a direct statement of what we intend - allowing both samba and httpd to
read files of type foo_t. This is also easier conceptually for those new to
policy development. I think that we are fixing a symptom with the extends
approach. The real problem is that the current policy is not structured to
provide macros with well-defined access semantics. If policy was written with
the abstractions, like above, the type union problem would not exist.
Additionally, the macros provide more control (there can be multiple version
with slightly different access - not possible with the extends even with the @)
and provide a single point for documentation.
I would like to see how some real world problems would be solved with the
extends syntax. I feel confident that every example could be expressed more
clearly through a set of well-thought out macros.
Thanks,
Karl
---
Karl MacMillan
Tresys Technology
http://www.tresys.com
(410) 290-1411 ext 134
> --
> Stephen Smalley <sds@tycho.nsa.gov>
> National Security Agency
>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-17 21:41 ` Karl MacMillan
@ 2005-03-18 13:13 ` Stephen Smalley
2005-03-18 13:56 ` Stephen Smalley
2005-03-18 22:28 ` Karl MacMillan
0 siblings, 2 replies; 58+ messages in thread
From: Stephen Smalley @ 2005-03-18 13:13 UTC (permalink / raw)
To: Karl MacMillan
Cc: 'Kaigai Kohei', 'KaiGai Kohei',
'SELinux Mail List', selinux-dev
On Thu, 2005-03-17 at 16:41 -0500, Karl MacMillan wrote:
> Yes - and I have already complained about those in another email. I'll be happy
> to send a patch disallowing complement in allow rules if you would accept it :)
I'd be willing to consider it; I'm not sure it is being used in any
allow rules presently, just in assertions, and the type set exclusion
(-) notation seems better suited for allow rules.
> I disagree - macros allow this. Also, what we want, I think, is not a union of
> types but an abstract notion of access. Your earlier example of
> samba_http_content_t is better expressed through:
>
> allow_samba_read(foo_t)
> allow_httpd_read(foo_t)
>
> This is a direct statement of what we intend - allowing both samba and httpd to
> read files of type foo_t.
Not exactly. What we want is a type that is accessible to httpd in the
same ways as httpd_content_t and that is accessible to samba in the same
ways as samba_share_t. Whether or not that means read-only, read-write,
or whatever depends on the allow rules, tunables, booleans, etc for
httpd and samba. So you would actually have to define macros expressing
the desired relationship between httpd and httpd_content_t and between
samba and samba_share_t, and use those macros for expressing those
relationships as well as for expressing the permissions for the new type
in order to ensure consistency. Further, this wouldn't necessarily
cover any other references to these types elsewhere, direct or indirect.
> I would like to see how some real world problems would be solved with the
> extends syntax. I feel confident that every example could be expressed more
> clearly through a set of well-thought out macros.
This is a good test for the extends syntax; does it help solve real
problems any better than the use of macros. A discussion on that issue
would be useful.
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-18 13:13 ` Stephen Smalley
@ 2005-03-18 13:56 ` Stephen Smalley
2005-03-18 22:28 ` Karl MacMillan
1 sibling, 0 replies; 58+ messages in thread
From: Stephen Smalley @ 2005-03-18 13:56 UTC (permalink / raw)
To: Karl MacMillan
Cc: 'Kaigai Kohei', 'KaiGai Kohei',
'SELinux Mail List', selinux-dev
On Fri, 2005-03-18 at 08:13 -0500, Stephen Smalley wrote:
> On Thu, 2005-03-17 at 16:41 -0500, Karl MacMillan wrote:
> > Yes - and I have already complained about those in another email. I'll be happy
> > to send a patch disallowing complement in allow rules if you would accept it :)
>
> I'd be willing to consider it; I'm not sure it is being used in any
> allow rules presently, just in assertions, and the type set exclusion
> (-) notation seems better suited for allow rules.
I'd also be happy to prohibit use of asterisk (*) in the type fields.
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-18 13:13 ` Stephen Smalley
2005-03-18 13:56 ` Stephen Smalley
@ 2005-03-18 22:28 ` Karl MacMillan
2005-03-18 23:03 ` Luke Kenneth Casson Leighton
1 sibling, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2005-03-18 22:28 UTC (permalink / raw)
To: 'Stephen Smalley'
Cc: 'Kaigai Kohei', 'KaiGai Kohei',
'SELinux Mail List', selinux-dev
> -----Original Message-----
> From: Stephen Smalley [mailto:sds@tycho.nsa.gov]
> Sent: Friday, March 18, 2005 8:14 AM
> To: Karl MacMillan
> Cc: 'Kaigai Kohei'; 'KaiGai Kohei'; 'SELinux Mail List';
> selinux-dev@tresys.com
> Subject: RE: [RFC & PATCH] inherited type definition.
>
> On Thu, 2005-03-17 at 16:41 -0500, Karl MacMillan wrote:
> > Yes - and I have already complained about those in another
> email. I'll
> > be happy to send a patch disallowing complement in allow
> rules if you
> > would accept it :)
>
> I'd be willing to consider it; I'm not sure it is being used
> in any allow rules presently, just in assertions, and the
> type set exclusion
> (-) notation seems better suited for allow rules.
>
Ok - I'll send you a patch.
> > I disagree - macros allow this. Also, what we want, I
> think, is not a
> > union of types but an abstract notion of access. Your
> earlier example
> > of samba_http_content_t is better expressed through:
> >
> > allow_samba_read(foo_t)
> > allow_httpd_read(foo_t)
> >
> > This is a direct statement of what we intend - allowing
> both samba and
> > httpd to read files of type foo_t.
>
> Not exactly. What we want is a type that is accessible to
> httpd in the same ways as httpd_content_t and that is
> accessible to samba in the same ways as samba_share_t.
> Whether or not that means read-only, read-write, or whatever
> depends on the allow rules, tunables, booleans, etc for httpd
> and samba.
I am saying, that if almost all access - including, for example, the access
between httpd and httpd_content_t - is expressed as a set of well-defined
macros, then this becomes easy. That means that a policy author can look at the
macros defining access between httpd and httpd_content_t and samba and
samba_share_t and then reuse those to create samba_httpd_content_t.
Also, the more I think about it the more convinced I am that the show-stopper
limitation of the extends syntax is that it allows only one subset of access.
The discussion so far has exposed that we don't usually want to grant all of the
access to httpd_content_t and samba_share_t to samba_httpd_content_t, but the @
syntax allows us to form only one subset. What if we want to create
ftp_httpd_content_t that has a different subset of the access to httpd_content_t
than is useful for samba_httpd_content_t? What if we want to give httpd the kind
of read access it has to httpd_content_t to foo_t and the kind of write access
it has to httpd_content_t to bar_t? With the extends syntax we are limited to
just one subset. The macros allow us to form arbitrary subsets of the access and
it apply to other types at will.
> So you would actually have to define macros
> expressing the desired relationship between httpd and
> httpd_content_t and between samba and samba_share_t, and use
> those macros for expressing those relationships as well as
> for expressing the permissions for the new type in order to
> ensure consistency.
Yes - exactly. I think that this has far-reaching benefits beyond this one use
case as well, including readability and documentation.
> Further, this wouldn't necessarily cover
> any other references to these types elsewhere, direct or indirect.
>
I think that this is a benefit - it makes the granting of access intentional and
explicit.
> > I would like to see how some real world problems would be
> solved with
> > the extends syntax. I feel confident that every example could be
> > expressed more clearly through a set of well-thought out macros.
>
> This is a good test for the extends syntax; does it help
> solve real problems any better than the use of macros. A
> discussion on that issue would be useful.
>
I agree, but I want to make certain that it is clear that I am not suggesting
that the current use of macros is an appropriate alternative. Also, we have
started a worked example of the macro abstraction that I am suggesting.
Unfortunately, it is a time-consuming task, but we have committed significant
resources to this as part of a larger effort to create a new security first
policy. As soon as possible, I'll start posting examples of how this is
progressing. My intuition says that this is the solution to a wide range of
policy writing difficulties and I am eager to have it tested and vetted.
Karl
---
Karl MacMillan
Tresys Technology
http://www.tresys.com
(410) 290-1411 ext 134
> --
> Stephen Smalley <sds@tycho.nsa.gov>
> National Security Agency
>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-18 22:28 ` Karl MacMillan
@ 2005-03-18 23:03 ` Luke Kenneth Casson Leighton
2005-03-20 23:20 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-18 23:03 UTC (permalink / raw)
To: Karl MacMillan
Cc: 'Stephen Smalley', 'Kaigai Kohei',
'KaiGai Kohei', 'SELinux Mail List', selinux-dev
On Fri, Mar 18, 2005 at 05:28:57PM -0500, Karl MacMillan wrote:
> Also, the more I think about it the more convinced I am that the show-stopper
> limitation of the extends syntax is that it allows only one subset of access.
there is nothing to stop you using an extends inside a macro:
$1_t EXTENDS $1_ftp_t
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-18 23:03 ` Luke Kenneth Casson Leighton
@ 2005-03-20 23:20 ` Karl MacMillan
2005-03-21 0:17 ` Luke Kenneth Casson Leighton
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2005-03-20 23:20 UTC (permalink / raw)
To: 'Luke Kenneth Casson Leighton'
Cc: 'Stephen Smalley', 'Kaigai Kohei',
'KaiGai Kohei', 'SELinux Mail List', selinux-dev
> -----Original Message-----
> From: Luke Kenneth Casson Leighton [mailto:lkcl@lkcl.net]
> Sent: Friday, March 18, 2005 6:04 PM
> To: Karl MacMillan
> Cc: 'Stephen Smalley'; 'Kaigai Kohei'; 'KaiGai Kohei';
> 'SELinux Mail List'; selinux-dev@tresys.com
> Subject: Re: [RFC & PATCH] inherited type definition.
>
> On Fri, Mar 18, 2005 at 05:28:57PM -0500, Karl MacMillan wrote:
> > Also, the more I think about it the more convinced I am that the
> > show-stopper limitation of the extends syntax is that it
> allows only one subset of access.
>
> there is nothing to stop you using an extends inside a macro:
>
> $1_t EXTENDS $1_ftp_t
>
> l.
>
How does this address the problem - only one subset of access from $1_ftp_t can
be marked with the @ syntax.
Karl
---
Karl MacMillan
Tresys Technology
http://www.tresys.com
(410) 290-1411 ext 134
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-20 23:20 ` Karl MacMillan
@ 2005-03-21 0:17 ` Luke Kenneth Casson Leighton
2005-03-21 13:39 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-21 0:17 UTC (permalink / raw)
To: Karl MacMillan
Cc: 'Stephen Smalley', 'Kaigai Kohei',
'KaiGai Kohei', 'SELinux Mail List', selinux-dev
On Sun, Mar 20, 2005 at 06:20:09PM -0500, Karl MacMillan wrote:
> > On Fri, Mar 18, 2005 at 05:28:57PM -0500, Karl MacMillan wrote:
> > > Also, the more I think about it the more convinced I am that the
> > > show-stopper limitation of the extends syntax is that it
> > allows only one subset of access.
> >
> > there is nothing to stop you using an extends inside a macro:
> >
> > $1_t EXTENDS $1_ftp_t
> >
> > l.
> >
>
> How does this address the problem - only one subset of access from $1_ftp_t can
> be marked with the @ syntax.
not that my opinion particularly matters or is authoritative
in any way, but i don't like the @ syntax - so i don't see it
as a problem, because i would never implement the @ syntax,
not in a million years.
the @ syntax goes against the "mandatory" grain in "MAC".
putting a wrapper (curly braces, brackets syntax, whatever is
most appropriate) around those sections which _are_ allowed
to be inherited is more along the MAC conceptual lines.
you could then potentially have an additional qualifier in your curly
braces wrapper which specifies _which_ children may "extend" a class
(remembering also to allow $1s etc to be substituted into that)
e.g.
some_macro (`
inheritable($1_ftp_t, parent_class2_t) {
allow ....;
}
allow ...;
')
then do this:
some_macro(user)
user_ftp_t EXTENDS user_t;
despite there being several things declared by the
some_macro(user), only SOME of those - those that are
EXPLICITLY ALLOWED TO BE INHERITED - permissions are duplicated
into the child, user_ftp_t.
... just to check: perhaps could i ask you to elaborate with
some examples because i may be getting the wrong end of the
stick / lost some context, here.
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-17 14:57 ` KaiGai Kohei
@ 2005-03-21 10:07 ` KaiGai Kohei
2005-03-21 15:59 ` Stephen Smalley
0 siblings, 1 reply; 58+ messages in thread
From: KaiGai Kohei @ 2005-03-21 10:07 UTC (permalink / raw)
To: KaiGai Kohei; +Cc: Stephen Smalley, Kaigai Kohei, SELinux Mail List
[-- Attachment #1: Type: text/plain, Size: 2101 bytes --]
Hi,
This attached patch implements (1) EXTENDS syntax with TYPE statement and
(2) '@' prefix to distinguish whether an assigned type/attribute includes
own child types or not.
(1) TYPE ... EXTENDS syntax
TYPE <typename> [ALIAS <aliases>] EXTENDS <type/attr>, <type/attr>, ...
The declared type can have the parents enumerated behind EXTENDS.
If we grant any permissions with '@' prefix, this permission is also
granted to own child types.
(2) '@' prefix
This is new feature from the former version.
If we specify the types (which have some child types) with '@' prefix to grant
permissions, the specified types is treated as the specified types directly
and those chils type.
If we specify the types without '@' prefix, such interpretation is not done.
By default, specifying the types are recognized same as current checkpolicy doing.
For Example:
attribute attr;
type X extends attr;
type Y extends X;
type A;
type B extends A;
type C extends A, X;
"allow @A A:file read;" is equal "allow {A B C} A:file read;".
"allow @A @A-@X:file read;" is equal "allow {A B C} {A B}:file read;".
"allow attr ~@X:file read;" is equal "allow {X Y C} {A B}:file read;".
We can use the '@' prefixi in following statements.
- ALLOW/AUDITALLOW/AUDITDENY/DONTAUDIT statements
- TYPE_TRANSITION/TYPE_MEMBER/TYPE_CHANGE statements
- ROLE/ROLE_TRANSITION statements.
- CONSTRAIN statements
- VALIDATETRANS statements (I was not sure)
- RANGE_TRANSITION statements (MLS statement, I was not sure)
In addition, the recognization of 'self' is changed from former version's patch.
In former version, "allow @A self:file read;" means "allow A {A B C}:file read;"
and "allow B B:file read;", "allow C C:file read;".
(I appended '@' for convenience.)
But in current version, "allow @A self:file read" means "allow {A B C} {A B C}:file read;".
Since I thought this interpretation is more aimple.
I checked this patch with 'sediff' and printf() in source.
If there are several good checking tools for such a purpose, I want you to teach.
Thanks,
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
[-- Attachment #2: checkpolicy-1.22-type_extends.2nd.patch --]
[-- Type: text/plain, Size: 22022 bytes --]
--- checkpolicy-1.22/checkpolicy.h 2005-01-26 14:16:20.000000000 -0500
+++ checkpolicy-1.22.extends.2nd/checkpolicy.h 2005-03-21 12:58:08.000000000 -0500
@@ -7,6 +7,7 @@ typedef struct te_assert {
ebitmap_t stypes;
ebitmap_t ttypes;
ebitmap_t tclasses;
+ ebitmap_t inherit;
int self;
access_vector_t *avp;
unsigned long line;
@@ -18,4 +19,16 @@ te_assert_t *te_assertions;
extern unsigned int policyvers;
extern unsigned int mlspol;
+/* type was not indexed in policydb,
+ but it's necessary for extends support. */
+extern type_datum_t **type_val_to_struct;
+extern int num_type_val_to_struct;
+extern void get_child_types(ebitmap_t *set, type_datum_t *t, int recursive);
+
+static inline type_datum_t *get_type(int typeval) {
+ if (!type_val_to_struct || typeval<1 || typeval>num_type_val_to_struct)
+ return NULL;
+ return type_val_to_struct[typeval-1];
+}
+
#endif
--- checkpolicy-1.22/checkpolicy.c 2005-01-26 14:16:20.000000000 -0500
+++ checkpolicy-1.22.extends.2nd/checkpolicy.c 2005-03-21 16:40:36.000000000 -0500
@@ -344,8 +344,10 @@ void check_assertion_helper(unsigned int
void check_assertions(void)
{
+ ebitmap_t temp;
+ type_datum_t *typedatum;
te_assert_t *a, *tmp;
- unsigned int i, j;
+ unsigned int i, j, k;
a = te_assertions;
while (a) {
@@ -353,7 +355,23 @@ void check_assertions(void)
if (!ebitmap_get_bit(&a->stypes, i))
continue;
if (a->self) {
- check_assertion_helper(i, i, &a->tclasses, a->avp, a->line);
+ typedatum = type_val_to_struct[i];
+ if (!typedatum) {
+ fprintf(stderr, "BUG: check_assetion for undefined type.\n");
+ exit(1);
+ }
+ ebitmap_init(&temp);
+ get_child_types(&temp, typedatum, ebitmap_get_bit(&a->inherit, i));
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if (!ebitmap_get_bit(&temp, j))
+ continue;
+ for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+ if (!ebitmap_get_bit(&temp, k))
+ continue;
+ check_assertion_helper(j, k, &a->tclasses, a->avp, a->line);
+ }
+ }
+ ebitmap_destroy(&temp);
}
for (j = ebitmap_startbit(&a->ttypes); j < ebitmap_length(&a->ttypes); j++) {
if (!ebitmap_get_bit(&a->ttypes, j))
@@ -366,6 +384,7 @@ void check_assertions(void)
ebitmap_destroy(&tmp->stypes);
ebitmap_destroy(&tmp->ttypes);
ebitmap_destroy(&tmp->tclasses);
+ ebitmap_destroy(&tmp->inherit);
free(tmp->avp);
free(tmp);
}
@@ -442,6 +461,49 @@ int change_bool(char *name, int state)
return 0;
}
+type_datum_t **type_val_to_struct = NULL;
+int num_type_val_to_struct = -1;
+
+static int type_val_to_struct_helper(hashtab_key_t k, hashtab_datum_t d, void *args)
+{
+ type_datum_t *t = (type_datum_t *)d;
+ if (!t->isattr && t->primary)
+ type_val_to_struct[t->value-1] = t;
+ return 0; /* always success */
+}
+
+void get_child_types(ebitmap_t *set, type_datum_t *td, int recur)
+{
+ type_datum_t *child;
+ int i;
+
+ if (!td->isattr && !td->primary)
+ td = get_type(td->value);
+
+ if (!td->isattr) {
+ ebitmap_set_bit(set, td->value - 1, 1);
+ if (!recur)
+ return;
+ for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+ if (!ebitmap_get_bit(&td->types, i))
+ continue;
+ child = type_val_to_struct[i];
+ get_child_types(set, child, recur);
+ }
+ } else {
+ for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+ if (!ebitmap_get_bit(&td->types, i))
+ continue;
+ if (!recur) {
+ ebitmap_set_bit(set, i, 1);
+ } else {
+ child = type_val_to_struct[i];
+ get_child_types(set, child, recur);
+ }
+ }
+ }
+}
+
int main(int argc, char **argv)
{
security_class_t tclass;
@@ -456,7 +518,7 @@ int main(int argc, char **argv)
unsigned int binary = 0, debug = 0;
struct val_to_name v;
int ret, ch, fd;
- unsigned int nel;
+ unsigned int nel, len;
struct stat sb;
void *map;
FILE *outfp = NULL;
@@ -593,6 +655,18 @@ int main(int argc, char **argv)
fprintf(stderr, "%s: error(s) encountered while parsing configuration\n", argv[0]);
exit(1);
}
+
+ /* construction of type_val_to_struct */
+ num_type_val_to_struct = policydbp->p_types.nprim;
+ len = sizeof(type_datum_t *) * num_type_val_to_struct;
+ type_val_to_struct = (type_datum_t **)malloc(len);
+ if (!type_val_to_struct) {
+ fprintf(stderr, "type_val_to_struct: out of memory\n");
+ exit(1);
+ }
+ memset(type_val_to_struct, 0, len);
+ hashtab_map(policydbp->p_types.table, type_val_to_struct_helper, NULL);
+
rewind(yyin);
policydb_lineno = 1;
source_file[0] = '\0';
--- checkpolicy-1.22/policy_scan.l 2005-02-17 09:59:23.000000000 -0500
+++ checkpolicy-1.22.extends.2nd/policy_scan.l 2005-03-21 12:23:17.000000000 -0500
@@ -78,6 +78,8 @@ ELSE |
else { return(ELSE); }
ALIAS |
alias { return(ALIAS); }
+EXTENDS |
+extends { return(EXTENDS); }
ATTRIBUTE |
attribute { return(ATTRIBUTE); }
TYPE_TRANSITION |
@@ -211,7 +213,8 @@ H2 { return(H2); }
"." |
"]" |
"~" |
-"*" { return(yytext[0]); }
+"*" |
+"@" { return(yytext[0]); }
. { yywarn("unrecognized character");}
%%
int yyerror(char *msg)
--- checkpolicy-1.22/policy_parse.y 2005-02-17 09:59:23.000000000 -0500
+++ checkpolicy-1.22.extends.2nd/policy_parse.y 2005-03-21 16:46:52.000000000 -0500
@@ -19,6 +19,11 @@
* the Free Software Foundation, version 2.
*/
+/* Updated: KaiGai Kohei, <kaigai@ak.jp.nec.com>
+ * Added inherited type extensions and '@' prefix. (2005/03/21)
+ */
+
+
/* FLASK */
%{
@@ -73,7 +78,7 @@ static int define_level(int range);
static int define_attrib(void);
static int define_typealias(void);
static int define_typeattribute(void);
-static int define_type(int alias);
+static int define_type(int alias, int extends);
static int define_compute_type(int which);
static int define_te_avtab(int which);
static int define_role_types(void);
@@ -133,6 +138,7 @@ static int define_ipv6_node_context(void
%token TYPE
%token TYPES
%token ALIAS
+%token EXTENDS
%token ATTRIBUTE
%token BOOL
%token IF
@@ -297,9 +303,13 @@ attribute_def : ATTRIBUTE iden
{ if (define_attrib()) return -1;}
;
type_def : TYPE identifier alias_def opt_attr_list ';'
- {if (define_type(1)) return -1;}
+ {if (define_type(1, 0)) return -1;}
| TYPE identifier opt_attr_list ';'
- {if (define_type(0)) return -1;}
+ {if (define_type(0, 0)) return -1;}
+ | TYPE identifier alias_def opt_extends_list ';'
+ {if (define_type(1, 1)) return -1;}
+ | TYPE identifier opt_extends_list ';'
+ {if (define_type(0, 1)) return -1;}
;
typealias_def : TYPEALIAS identifier alias_def ';'
{if (define_typealias()) return -1;}
@@ -310,6 +320,8 @@ typeattribute_def : TYPEATTRIBUTE identi
opt_attr_list : ',' id_comma_list
|
;
+opt_extends_list : EXTENDS id_comma_list
+ ;
bool_def : BOOL identifier bool_val ';'
{if (define_bool()) return -1;}
;
@@ -511,13 +523,13 @@ cexpr_prim : U1 op U2
| R3 op { if (insert_separator(1)) return -1; } names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_XTARGET), $2);
if ($$ == 0) return -1; }
- | T1 op { if (insert_separator(1)) return -1; } names_push
+ | T1 op { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, $2);
if ($$ == 0) return -1; }
- | T2 op { if (insert_separator(1)) return -1; } names_push
+ | T2 op { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), $2);
if ($$ == 0) return -1; }
- | T3 op { if (insert_separator(1)) return -1; } names_push
+ | T3 op { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_XTARGET), $2);
if ($$ == 0) return -1; }
| SAMEUSER
@@ -532,10 +544,10 @@ cexpr_prim : U1 op U2
| ROLE role_mls_op
{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
if ($$ == 0) return -1; }
- | SOURCE TYPE { if (insert_separator(1)) return -1; } names_push
+ | SOURCE TYPE { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ);
if ($$ == 0) return -1; }
- | TARGET TYPE { if (insert_separator(1)) return -1; } names_push
+ | TARGET TYPE { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), CEXPR_EQ);
if ($$ == 0) return -1; }
| L1 role_mls_op L2
@@ -695,20 +707,27 @@ tilde : '~'
;
asterisk : '*'
;
-names : identifier
+atmark : '@'
+ ;
+type_identifier : IDENTIFIER
+ { if (insert_id(yytext, 0)) return -1; }
+ | atmark IDENTIFIER
+ { if (insert_id("@", 0) || insert_id(yytext, 0)) return -1; }
+ ;
+names : type_identifier
{ if (insert_separator(0)) return -1; }
| nested_id_set
{ if (insert_separator(0)) return -1; }
| asterisk
{ if (insert_id("*", 0)) return -1;
if (insert_separator(0)) return -1; }
- | tilde identifier
+ | tilde type_identifier
{ if (insert_id("~", 0)) return -1;
if (insert_separator(0)) return -1; }
| tilde nested_id_set
- { if (insert_id("~", 0)) return -1;
+ { if (insert_id("~", 0)) return -1;
if (insert_separator(0)) return -1; }
- | identifier '-' { if (insert_id("-", 0)) return -1; } identifier
+ | type_identifier '-' { if (insert_id("-", 0)) return -1; } type_identifier
{ if (insert_separator(0)) return -1; }
;
tilde_push : tilde
@@ -717,6 +736,19 @@ tilde_push : tilde
asterisk_push : asterisk
{ if (insert_id("*", 1)) return -1; }
;
+type_names_push : type_identifier_push
+ | '{' type_identifier_list_push '}'
+ | tilde_push type_identifier_push
+ | tilde_push '{' type_identifier_list_push '}'
+ ;
+type_identifier_list_push : type_identifier_push
+ | type_identifier_list_push type_identifier_push
+ ;
+type_identifier_push : IDENTIFIER
+ { if (insert_id(yytext,1)) return -1; }
+ | atmark IDENTIFIER
+ { if (insert_id(yytext,1)||insert_id("@",1)) return -1;}
+ ;
names_push : identifier_push
| '{' identifier_list_push '}'
| asterisk_push
@@ -736,7 +768,9 @@ nested_id_set : '{' nested_id_
;
nested_id_list : nested_id_element | nested_id_list nested_id_element
;
-nested_id_element : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set
+nested_id_element : type_identifier
+ | '-' { if (insert_id("-", 0)) return -1; } type_identifier
+ | nested_id_set
;
identifier : IDENTIFIER
{ if (insert_id(yytext,0)) return -1; }
@@ -1596,10 +1630,10 @@ static int define_typeattribute(void)
return 0;
}
-static int define_type(int alias)
+static int define_type(int alias, int extends)
{
char *id;
- type_datum_t *datum, *aliasdatum, *attr;
+ type_datum_t *datum, *aliasdatum, *inherit;
int ret, newattr = 0;
@@ -1677,9 +1711,10 @@ static int define_type(int alias)
}
while ((id = queue_remove(id_queue))) {
- attr = hashtab_search(policydbp->p_types.table, id);
- if (!attr) {
- sprintf(errormsg, "attribute %s is not declared", id);
+ inherit = hashtab_search(policydbp->p_types.table, id);
+ if (!inherit) {
+ sprintf(errormsg, "%sattribute %s is not declared",
+ (extends)?"type/":"", id);
#if 1
/* treat it as a fatal error */
yyerror(errormsg);
@@ -1708,7 +1743,7 @@ static int define_type(int alias)
newattr = 0;
}
- if (!attr->isattr) {
+ if (!extends && !inherit->isattr) {
sprintf(errormsg, "%s is a type, not an attribute", id);
yyerror(errormsg);
return -1;
@@ -1717,7 +1752,7 @@ static int define_type(int alias)
if (!newattr)
free(id);
- ebitmap_set_bit(&attr->types, datum->value - 1, TRUE);
+ ebitmap_set_bit(&inherit->types, datum->value - 1, TRUE);
}
return 0;
@@ -1759,11 +1794,13 @@ static char *type_val_to_name(unsigned i
static int set_types(ebitmap_t *set,
ebitmap_t *negset,
+ ebitmap_t *inherit,
char *id,
int *add)
{
type_datum_t *t;
unsigned int i;
+ ebitmap_t temp;
if (strcmp(id, "*") == 0) {
/* set all types not in negset */
@@ -1788,10 +1825,16 @@ static int set_types(ebitmap_t *set,
}
if (strcmp(id, "-") == 0) {
- *add = 0;
+ *add &= 0xfffe; /* clear bit 0*/
+ free(id);
+ return 0;
+ }
+
+ if (strcmp(id, "@") == 0) {
+ *add |= 0x0002; /* set bit 1 */
free(id);
return 0;
- }
+ }
t = hashtab_search(policydbp->p_types.table, id);
if (!t) {
@@ -1800,42 +1843,28 @@ static int set_types(ebitmap_t *set,
free(id);
return -1;
}
+ if (inherit && ((*add)&0x0002)!=0 )
+ ebitmap_set_bit(inherit, t->value - 1, TRUE);
- if (t->isattr) {
- /* set or clear all types with this attribute,
- but do not set anything explicitly cleared previously */
- for (i = ebitmap_startbit(&t->types); i < ebitmap_length(&t->types); i++) {
- if (!ebitmap_get_bit(&t->types, i))
- continue;
- if (!(*add)) {
- ebitmap_set_bit(set, i, FALSE);
- ebitmap_set_bit(negset, i, TRUE);
- } else if (!ebitmap_get_bit(negset, i)) {
- ebitmap_set_bit(set, i, TRUE);
-#if VERBOSE
- } else {
- char *name = type_val_to_name(i+1);
- sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
- yywarn(errormsg);
-#endif
- }
- }
- } else {
- /* set or clear one type, but do not set anything
- explicitly cleared previously */
- if (!(*add)) {
- ebitmap_set_bit(set, t->value - 1, FALSE);
- ebitmap_set_bit(negset, t->value - 1, TRUE);
- } else if (!ebitmap_get_bit(negset, t->value - 1)) {
- ebitmap_set_bit(set, t->value - 1, TRUE);
+ ebitmap_init(&temp);
+ get_child_types(&temp, t, (*add)&0x0002);
+ for (i = ebitmap_startbit(&temp); i < ebitmap_length(&temp); i++) {
+ if (!ebitmap_get_bit(&temp, i))
+ continue;
+ if (!((*add)&0x0001)) {
+ ebitmap_set_bit(set, i, FALSE);
+ ebitmap_set_bit(negset, i, TRUE);
+ } else if (!ebitmap_get_bit(negset, i)) {
+ ebitmap_set_bit(set, i, TRUE);
#if VERBOSE
} else {
- sprintf(errormsg, "ignoring %s due to prior -%s", id, id);
+ char *name = type_val_to_name(i+1);
+ sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
yywarn(errormsg);
#endif
}
}
-
+ ebitmap_destroy(&temp);
free(id);
*add = 1;
return 0;
@@ -1872,14 +1901,14 @@ static int define_compute_type(int which
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -2012,14 +2041,14 @@ static cond_av_list_t *define_cond_compu
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, NULL, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
@@ -2419,9 +2448,10 @@ static cond_av_list_t *define_cond_te_av
cond_av_list_t *sub_list, *final_list, *tail;
class_datum_t *cladatum;
perm_datum_t *perdatum;
- ebitmap_t stypes, ttypes, tclasses, negset;
+ type_datum_t *typedatum;
+ ebitmap_t stypes, ttypes, tclasses, temp, inherit, negset;
access_vector_t *avp;
- int i, j, hiclass, self = 0, add = 1;
+ int i, j, k, hiclass, self = 0, add = 1;
int suppress = 0;
if (pass == 1) {
@@ -2439,10 +2469,11 @@ static cond_av_list_t *define_cond_te_av
ebitmap_init(&stypes);
ebitmap_init(&ttypes);
ebitmap_init(&tclasses);
+ ebitmap_init(&inherit);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, &inherit, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
@@ -2453,7 +2484,7 @@ static cond_av_list_t *define_cond_te_av
self = 1;
continue;
}
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
@@ -2542,19 +2573,36 @@ static cond_av_list_t *define_cond_te_av
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
if (!ebitmap_get_bit(&stypes, i))
continue;
- if (self) {
- if ((sub_list = cond_te_avtab_helper(which, i, i, &tclasses, avp )) == COND_ERR)
- return COND_ERR;
- if (final_list) {
- tail->next = sub_list;
- while (tail->next != NULL)
- tail = tail->next;
- } else {
- final_list = sub_list;
- tail = final_list;
- while (tail->next != NULL)
- tail = tail->next;
+ typedatum = get_type(i+1);
+ if (!typedatum)
+ return COND_ERR;
+ ebitmap_init(&temp);
+ /* If the source type is given with '@' prefix,
+ 'self' also includes own child types. */
+ get_child_types(&temp, typedatum, ebitmap_get_bit(&inherit,i));
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if(!ebitmap_get_bit(&temp, j))
+ continue;
+ for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+ if(!ebitmap_get_bit(&temp, k))
+ continue;
+ sub_list = cond_te_avtab_helper(which, j, k, &tclasses, avp);
+ if (sub_list==COND_ERR) {
+ ebitmap_destroy(&temp);
+ return COND_ERR;
+ }
+ if (final_list) {
+ tail->next = sub_list;
+ while (tail->next != NULL)
+ tail = tail->next;
+ } else {
+ final_list = sub_list;
+ tail = final_list;
+ while (tail->next != NULL)
+ tail = tail->next;
+ }
}
+ ebitmap_destroy(&temp);
}
}
}
@@ -2595,9 +2643,10 @@ static int define_te_avtab(int which)
char *id;
class_datum_t *cladatum;
perm_datum_t *perdatum;
- ebitmap_t stypes, ttypes, tclasses, negset;
+ type_datum_t *typedatum;
+ ebitmap_t stypes, ttypes, tclasses, temp, inherit, negset;
access_vector_t *avp;
- unsigned int i, j, hiclass;
+ unsigned int i, j, k, hiclass;
int self = 0, add = 1;
te_assert_t *newassert;
int suppress = 0;
@@ -2617,10 +2666,11 @@ static int define_te_avtab(int which)
ebitmap_init(&stypes);
ebitmap_init(&ttypes);
ebitmap_init(&tclasses);
+ ebitmap_init(&inherit);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, &inherit, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -2631,7 +2681,7 @@ static int define_te_avtab(int which)
self = 1;
continue;
}
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -2723,6 +2773,7 @@ static int define_te_avtab(int which)
newassert->stypes = stypes;
newassert->ttypes = ttypes;
newassert->tclasses = tclasses;
+ newassert->inherit = inherit;
newassert->self = self;
newassert->avp = avp;
newassert->line = policydb_lineno;
@@ -2735,8 +2786,26 @@ static int define_te_avtab(int which)
if (!ebitmap_get_bit(&stypes, i))
continue;
if (self) {
- if (te_avtab_helper(which, i, i, &tclasses, avp))
+ typedatum = get_type(i+1);
+ if (!typedatum)
return -1;
+ ebitmap_init(&temp);
+ /* If the source type is given with '@' prefix,
+ 'self' means own child types. */
+ get_child_types(&temp, typedatum, ebitmap_get_bit(&inherit, i));
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if (!ebitmap_get_bit(&temp, j))
+ continue;
+ for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+ if (!ebitmap_get_bit(&temp, k))
+ continue;
+ if (te_avtab_helper(which, j, k, &tclasses, avp)) {
+ ebitmap_destroy(&temp);
+ return -1;
+ }
+ }
+ }
+ ebitmap_destroy(&temp);
}
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
if (!ebitmap_get_bit(&ttypes, j))
@@ -2827,7 +2896,7 @@ static int define_role_types(void)
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&role->types, &negset, id, &add))
+ if (set_types(&role->types, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -3042,7 +3111,7 @@ static int define_role_trans(void)
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&types, &negset, id, &add))
+ if (set_types(&types, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -3467,7 +3536,7 @@ static uintptr_t
}
val = role->value;
} else if (expr->attr & CEXPR_TYPE) {
- if (set_types(&expr->names, &negset, id, &add)) {
+ if (set_types(&expr->names, &negset, NULL, id, &add)) {
free(expr);
return 0;
}
@@ -4903,14 +4972,14 @@ static int define_range_trans(void)
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&doms, &negset, id, &add))
+ if (set_types(&doms, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&types, &negset, id, &add))
+ if (set_types(&types, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-21 0:17 ` Luke Kenneth Casson Leighton
@ 2005-03-21 13:39 ` Karl MacMillan
2005-03-22 0:14 ` Luke Kenneth Casson Leighton
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2005-03-21 13:39 UTC (permalink / raw)
To: 'Luke Kenneth Casson Leighton'
Cc: 'Stephen Smalley', 'Kaigai Kohei',
'KaiGai Kohei', 'SELinux Mail List', selinux-dev
> -----Original Message-----
> From: Luke Kenneth Casson Leighton [mailto:lkcl@lkcl.net]
> Sent: Sunday, March 20, 2005 7:17 PM
> To: Karl MacMillan
> Cc: 'Stephen Smalley'; 'Kaigai Kohei'; 'KaiGai Kohei';
> 'SELinux Mail List'; selinux-dev@tresys.com
> Subject: Re: [RFC & PATCH] inherited type definition.
>
> On Sun, Mar 20, 2005 at 06:20:09PM -0500, Karl MacMillan wrote:
>
> > > On Fri, Mar 18, 2005 at 05:28:57PM -0500, Karl MacMillan wrote:
> > > > Also, the more I think about it the more convinced I am
> that the
> > > > show-stopper limitation of the extends syntax is that it
> > > allows only one subset of access.
> > >
> > > there is nothing to stop you using an extends inside a macro:
> > >
> > > $1_t EXTENDS $1_ftp_t
> > >
> > > l.
> > >
> >
> > How does this address the problem - only one subset of access from
> > $1_ftp_t can be marked with the @ syntax.
>
> not that my opinion particularly matters or is authoritative
> in any way, but i don't like the @ syntax - so i don't see
> it as a problem, because i would never implement the @
> syntax, not in a million years.
>
> the @ syntax goes against the "mandatory" grain in "MAC".
>
> putting a wrapper (curly braces, brackets syntax, whatever
> is most appropriate) around those sections which _are_
> allowed to be inherited is more along the MAC conceptual lines.
>
> you could then potentially have an additional qualifier in
> your curly braces wrapper which specifies _which_ children
> may "extend" a class (remembering also to allow $1s etc to
> be substituted into that)
>
> e.g.
>
> some_macro (`
> inheritable($1_ftp_t, parent_class2_t) {
>
> allow ....;
>
> }
> allow ...;
> ')
>
>
> then do this:
>
> some_macro(user)
> user_ftp_t EXTENDS user_t;
>
> despite there being several things declared by the
> some_macro(user), only SOME of those - those that are
> EXPLICITLY ALLOWED TO BE INHERITED - permissions are
> duplicated into the child, user_ftp_t.
>
First, you missed the switch to the @ being required in order to inherit
permissions through extends - making that syntax, as far as I can tell, the same
as what you are suggesting. Next, my objection is that there is only one subset
of permissions - there is no way to have user_ftp_t inherit one set of
permissions from user_t and user_httpd_t inherit another set of permissions from
user_t. My assertion is that this is ultimately too limiting and makes this
syntax only useful for contrived examples.
Karl
>
> ... just to check: perhaps could i ask you to elaborate with
> some examples because i may be getting the wrong end of the
> stick / lost some context, here.
>
> l.
>
---
Karl MacMillan
Tresys Technology
http://www.tresys.com
(410) 290-1411 ext 134
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-21 10:07 ` KaiGai Kohei
@ 2005-03-21 15:59 ` Stephen Smalley
2005-03-23 8:17 ` Kaigai Kohei
0 siblings, 1 reply; 58+ messages in thread
From: Stephen Smalley @ 2005-03-21 15:59 UTC (permalink / raw)
To: KaiGai Kohei; +Cc: Kaigai Kohei, SELinux Mail List
On Mon, 2005-03-21 at 19:07 +0900, KaiGai Kohei wrote:
> This attached patch implements (1) EXTENDS syntax with TYPE statement and
> (2) '@' prefix to distinguish whether an assigned type/attribute includes
> own child types or not.
Thanks for this revised patch. I think at this point we need some
concrete examples of how this new language extension can be applied to
solve real problems in a manner that is superior to the use of macros
(or alternatively, if the language supported them, templates of some
kind). That will help us determine whether this language extension is
justified.
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-21 13:39 ` Karl MacMillan
@ 2005-03-22 0:14 ` Luke Kenneth Casson Leighton
2005-03-22 13:53 ` Karl MacMillan
0 siblings, 1 reply; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-22 0:14 UTC (permalink / raw)
To: Karl MacMillan
Cc: 'Stephen Smalley', 'Kaigai Kohei',
'KaiGai Kohei', 'SELinux Mail List', selinux-dev
On Mon, Mar 21, 2005 at 08:39:48AM -0500, Karl MacMillan wrote:
> > -----Original Message-----
> > From: Luke Kenneth Casson Leighton [mailto:lkcl@lkcl.net]
> > Sent: Sunday, March 20, 2005 7:17 PM
> > To: Karl MacMillan
> > Cc: 'Stephen Smalley'; 'Kaigai Kohei'; 'KaiGai Kohei';
> > 'SELinux Mail List'; selinux-dev@tresys.com
> > Subject: Re: [RFC & PATCH] inherited type definition.
> >
> > On Sun, Mar 20, 2005 at 06:20:09PM -0500, Karl MacMillan wrote:
> >
> > > > On Fri, Mar 18, 2005 at 05:28:57PM -0500, Karl MacMillan wrote:
> > > > > Also, the more I think about it the more convinced I am
> > that the
> > > > > show-stopper limitation of the extends syntax is that it
> > > > allows only one subset of access.
> > > >
> > > > there is nothing to stop you using an extends inside a macro:
> > > >
> > > > $1_t EXTENDS $1_ftp_t
> > > >
> > > > l.
> > > >
> > >
> > > How does this address the problem - only one subset of access from
> > > $1_ftp_t can be marked with the @ syntax.
> >
> > not that my opinion particularly matters or is authoritative
> > in any way, but i don't like the @ syntax - so i don't see
> > it as a problem, because i would never implement the @
> > syntax, not in a million years.
> >
> > the @ syntax goes against the "mandatory" grain in "MAC".
> >
> > putting a wrapper (curly braces, brackets syntax, whatever
> > is most appropriate) around those sections which _are_
> > allowed to be inherited is more along the MAC conceptual lines.
> >
> > you could then potentially have an additional qualifier in
> > your curly braces wrapper which specifies _which_ children
> > may "extend" a class (remembering also to allow $1s etc to
> > be substituted into that)
> >
> > e.g.
> >
> > some_macro (`
> > inheritable($1_ftp_t, parent_class2_t) {
> >
> > allow ....;
> >
> > }
> > allow ...;
> > ')
> >
> >
> > then do this:
> >
> > some_macro(user)
> > user_ftp_t EXTENDS user_t;
> >
> > despite there being several things declared by the
> > some_macro(user), only SOME of those - those that are
> > EXPLICITLY ALLOWED TO BE INHERITED - permissions are
> > duplicated into the child, user_ftp_t.
> >
>
> First, you missed the switch to the @ being required in order to inherit
> permissions through extends - making that syntax, as far as I can tell, the same
> as what you are suggesting.
i understood it to be the other way round - that the @ is required to
_not_ allow a permission to be inherited through extends.
> Next, my objection is that there is only one subset
> of permissions - there is no way to have user_ftp_t inherit one set of
> permissions from user_t and user_httpd_t inherit another set of permissions from
> user_t.
note syntax in example [copied from above]:
> > some_macro (`
> > inheritable($1_ftp_t, parent_class2_t) {
^^^^^^^^ ^^^^^^^^^^^^^^^
> >
> > allow ....;
> >
> > }
so, to link this with your examples above, let's express this in
"inheritable() { ... }" syntax:
some_macro (`
inheritable($1_ftp_t, $1_httpd_t) {
allow ....;
}
inheritable($1_ftp_t) {
allow ....;
}
inheritable($1_httpd_t) {
allow ....;
}
allow ....;
}
')
make sense?
i believe that this covers the objection that you raise:
clarification from you that it does, greatly appreciated.
if you _really_ wanted to use the @ syntax (and @ means
"inherit is okay" rather than "inherit isn't possible"), how
about extending the @ syntax to also make it possible to do
@{$1_ftp_t, $1_httpd_t} similar to above?
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* RE: [RFC & PATCH] inherited type definition.
2005-03-22 0:14 ` Luke Kenneth Casson Leighton
@ 2005-03-22 13:53 ` Karl MacMillan
2005-03-24 11:04 ` Luke Kenneth Casson Leighton
0 siblings, 1 reply; 58+ messages in thread
From: Karl MacMillan @ 2005-03-22 13:53 UTC (permalink / raw)
To: 'Luke Kenneth Casson Leighton'
Cc: 'Stephen Smalley', 'Kaigai Kohei',
'KaiGai Kohei', 'SELinux Mail List', selinux-dev
> -----Original Message-----
> From: Luke Kenneth Casson Leighton [mailto:lkcl@lkcl.net]
> Sent: Monday, March 21, 2005 7:15 PM
<snip>
> >
> > First, you missed the switch to the @ being required in order to
> > inherit permissions through extends - making that syntax,
> as far as I
> > can tell, the same as what you are suggesting.
>
> i understood it to be the other way round - that the @ is
> required to _not_ allow a permission to be inherited through extends.
>
>
Like I said - it switched part way through the discussion.
>
> > Next, my objection is that there is only one subset of
> permissions -
> > there is no way to have user_ftp_t inherit one set of
> permissions from
> > user_t and user_httpd_t inherit another set of permissions from
> > user_t.
>
> note syntax in example [copied from above]:
>
> > > some_macro (`
> > > inheritable($1_ftp_t, parent_class2_t) {
> ^^^^^^^^ ^^^^^^^^^^^^^^^
> > >
> > > allow ....;
> > >
> > > }
>
> so, to link this with your examples above, let's express this in
> "inheritable() { ... }" syntax:
>
> some_macro (`
> inheritable($1_ftp_t, $1_httpd_t) {
> allow ....;
> }
> inheritable($1_ftp_t) {
> allow ....;
> }
> inheritable($1_httpd_t) {
> allow ....;
> }
> allow ....;
> }
>
> ')
>
> make sense?
>
I guess I don't understand how your proposed syntax works. What does it mean
when there are two types?
Karl
---
Karl MacMillan
Tresys Technology
http://www.tresys.com
(410) 290-1411 ext 134
> i believe that this covers the objection that you raise:
> clarification from you that it does, greatly appreciated.
>
> if you _really_ wanted to use the @ syntax (and @ means
> "inherit is okay" rather than "inherit isn't possible"), how
> about extending the @ syntax to also make it possible to do
> @{$1_ftp_t, $1_httpd_t} similar to above?
>
> l.
>
>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-21 15:59 ` Stephen Smalley
@ 2005-03-23 8:17 ` Kaigai Kohei
2005-03-23 13:56 ` Stephen Smalley
2005-03-24 11:06 ` Luke Kenneth Casson Leighton
0 siblings, 2 replies; 58+ messages in thread
From: Kaigai Kohei @ 2005-03-23 8:17 UTC (permalink / raw)
To: Stephen Smalley; +Cc: KaiGai Kohei, SELinux Mail List
[-- Attachment #1: Type: text/plain, Size: 4069 bytes --]
Hi,
The attached (3rd) patch implements TYPEEXTENDS statement in addition
to the latest patch. Because TYPE ... EXTENDS statements can not handle
forwarding loopup, TYPEEXTENDS statement is necessary to represent
inheritance-relationship not to depend on the definition placement.
TYPEEXTENDS <type-name> EXTENDS <type/attr>, <type/attr>, ... ;
(*) <type-name> and <type/attr> must have been defined.
This is almost the same as TYPEATTRIBUTE.
> Thanks for this revised patch. I think at this point we need some
> concrete examples of how this new language extension can be applied to
> solve real problems in a manner that is superior to the use of macros
> (or alternatively, if the language supported them, templates of some
> kind). That will help us determine whether this language extension is
> justified.
I tried to modify the Fedora-C3's strict policy for quick testing,
and represent a unified file type of HTTPd/Samba/FTPd.
I intend to access /var/www/ftp via HTTP and FTP, /var/www/samba via HTTP and Samba.
The following configuration was necessary for this purpose.
BTW, since any macros (such as apache) were so complex for me, the following
configuration may be insufficiency in a precise sense.
But it's easily understandable as a configuration sample for real application,
I think.
Thanks,
o samba.te was modified as follows:
--- policy.orig/domains/program/samba.te 2005-03-23 03:52:39.000000000 -0500
+++ policy.kaigai/domains/program/samba.te 2005-03-23 04:04:45.000000000 -0500
@@ -75,6 +75,8 @@
# Access Samba shares.
-allow smbd_t samba_share_t:dir create_dir_perms;
-allow smbd_t samba_share_t:file create_file_perms;
+attribute samba_share_path;
+allow smbd_t samba_share_path:dir {getattr search};
+allow smbd_t @samba_share_t:dir create_dir_perms;
+allow smbd_t @samba_share_t:file create_file_perms;
ifdef(`logrotate.te', `
o apache_macros.te was modified as follows:
--- policy.orig/macros/program/apache_macros.te 2005-03-23 03:52:39.000000000 -0500
+++ policy.kaigai/macros/program/apache_macros.te 2005-03-23 03:39:57.000000000 -0500
@@ -172,9 +172,9 @@
# Allow the web server to run scripts and serve pages
##############################################################
-r_dir_file(httpd_t, httpd_$1_content_t)
+r_dir_file(httpd_t, @httpd_$1_content_t)
-allow httpd_t httpd_$1_htaccess_t: file r_file_perms;
+allow httpd_t @httpd_$1_htaccess_t: file r_file_perms;
-r_dir_file(httpd_t, httpd_$1_script_rw_t)
+r_dir_file(httpd_t, @httpd_$1_script_rw_t)
############################################
o ftpd.te was modified as follows:
--- policy.orig/domains/program/ftpd.te 2005-03-23 03:52:38.000000000 -0500
+++ policy.kaigai/domains/program/ftpd.te 2005-03-23 04:03:11.000000000 -0500
@@ -105,2 +105,9 @@
')dnl end if nfs_home_dirs
dontaudit ftpd_t selinux_config_t:dir { search };
+
+attribute ftp_content_path;
+type ftp_content_t alias ftpd_anon_t extends ftp_content_path;
+allow ftpd_t @ftp_content_path:dir {getattr search};
+r_dir_file(ftpd_t, @ftp_content_t);
+file_type_auto_trans(ftpd_t, @ftp_content_t, ftp_content_t)
+
o And, private additional configuration is as follows:
--- /dev/null 2005-03-22 18:46:01.562514976 -0500
+++ policy.kaigai/inaddition.te 2005-03-23 04:06:49.576548144 -0500
@@ -0,0 +1,7 @@
+# necessity for access path
+typeattribute var_t ftp_content_path, samba_share_path;
+typeattribute httpd_sys_content_t ftp_content_path, samba_share_path;
+# definition of unified file type
+type httpd_ftp_t extends httpd_sys_content_t, ftp_content_t;
+type httpd_samba_t extends httpd_sys_content_t, samba_share_t;
o File labeling
/var system_u:object_r:var_t
/var/www system_u:object_r:httpd_sys_content_t
/var/www/ftp system_u:object_r:httpd_ftp_t
/var/www/ftp/index.html system_u:object_r:httpd_ftp_t
/var/www/samba system_u:object_r:httpd_samba_t
/var/www/samba/index.html system_u:object_r:httpd_samba_t
--
Linux Promotion Center, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>
[-- Attachment #2: checkpolicy-1.22-type_extends.3rd.patch --]
[-- Type: text/plain, Size: 24872 bytes --]
--- checkpolicy-1.22/checkpolicy.h 2005-01-27 04:16:20.000000000 +0900
+++ checkpolicy-1.22.extends.3rd/checkpolicy.h 2005-03-23 08:31:03.000000000 +0900
@@ -7,6 +7,7 @@ typedef struct te_assert {
ebitmap_t stypes;
ebitmap_t ttypes;
ebitmap_t tclasses;
+ ebitmap_t inherit;
int self;
access_vector_t *avp;
unsigned long line;
@@ -18,4 +19,16 @@ te_assert_t *te_assertions;
extern unsigned int policyvers;
extern unsigned int mlspol;
+/* type was not indexed in policydb,
+ but it's necessary for extends support. */
+extern type_datum_t **type_val_to_struct;
+extern int num_type_val_to_struct;
+extern void get_child_types(ebitmap_t *set, type_datum_t *t, int recursive);
+
+static inline type_datum_t *get_type(int typeval) {
+ if (!type_val_to_struct || typeval<1 || typeval>num_type_val_to_struct)
+ return NULL;
+ return type_val_to_struct[typeval-1];
+}
+
#endif
--- checkpolicy-1.22/checkpolicy.c 2005-01-27 04:16:20.000000000 +0900
+++ checkpolicy-1.22.extends.3rd/checkpolicy.c 2005-03-23 08:31:03.000000000 +0900
@@ -344,8 +344,10 @@ void check_assertion_helper(unsigned int
void check_assertions(void)
{
+ ebitmap_t temp;
+ type_datum_t *typedatum;
te_assert_t *a, *tmp;
- unsigned int i, j;
+ unsigned int i, j, k;
a = te_assertions;
while (a) {
@@ -353,7 +355,23 @@ void check_assertions(void)
if (!ebitmap_get_bit(&a->stypes, i))
continue;
if (a->self) {
- check_assertion_helper(i, i, &a->tclasses, a->avp, a->line);
+ typedatum = type_val_to_struct[i];
+ if (!typedatum) {
+ fprintf(stderr, "BUG: check_assetion for undefined type.\n");
+ exit(1);
+ }
+ ebitmap_init(&temp);
+ get_child_types(&temp, typedatum, ebitmap_get_bit(&a->inherit, i));
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if (!ebitmap_get_bit(&temp, j))
+ continue;
+ for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+ if (!ebitmap_get_bit(&temp, k))
+ continue;
+ check_assertion_helper(j, k, &a->tclasses, a->avp, a->line);
+ }
+ }
+ ebitmap_destroy(&temp);
}
for (j = ebitmap_startbit(&a->ttypes); j < ebitmap_length(&a->ttypes); j++) {
if (!ebitmap_get_bit(&a->ttypes, j))
@@ -366,6 +384,7 @@ void check_assertions(void)
ebitmap_destroy(&tmp->stypes);
ebitmap_destroy(&tmp->ttypes);
ebitmap_destroy(&tmp->tclasses);
+ ebitmap_destroy(&tmp->inherit);
free(tmp->avp);
free(tmp);
}
@@ -442,6 +461,49 @@ int change_bool(char *name, int state)
return 0;
}
+type_datum_t **type_val_to_struct = NULL;
+int num_type_val_to_struct = -1;
+
+static int type_val_to_struct_helper(hashtab_key_t k, hashtab_datum_t d, void *args)
+{
+ type_datum_t *t = (type_datum_t *)d;
+ if (!t->isattr && t->primary)
+ type_val_to_struct[t->value-1] = t;
+ return 0; /* always success */
+}
+
+void get_child_types(ebitmap_t *set, type_datum_t *td, int recur)
+{
+ type_datum_t *child;
+ int i;
+
+ if (!td->isattr && !td->primary)
+ td = get_type(td->value);
+
+ if (!td->isattr) {
+ ebitmap_set_bit(set, td->value - 1, 1);
+ if (!recur)
+ return;
+ for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+ if (!ebitmap_get_bit(&td->types, i))
+ continue;
+ child = type_val_to_struct[i];
+ get_child_types(set, child, recur);
+ }
+ } else {
+ for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+ if (!ebitmap_get_bit(&td->types, i))
+ continue;
+ if (!recur) {
+ ebitmap_set_bit(set, i, 1);
+ } else {
+ child = type_val_to_struct[i];
+ get_child_types(set, child, recur);
+ }
+ }
+ }
+}
+
int main(int argc, char **argv)
{
security_class_t tclass;
@@ -456,7 +518,7 @@ int main(int argc, char **argv)
unsigned int binary = 0, debug = 0;
struct val_to_name v;
int ret, ch, fd;
- unsigned int nel;
+ unsigned int nel, len;
struct stat sb;
void *map;
FILE *outfp = NULL;
@@ -593,6 +655,18 @@ int main(int argc, char **argv)
fprintf(stderr, "%s: error(s) encountered while parsing configuration\n", argv[0]);
exit(1);
}
+
+ /* construction of type_val_to_struct */
+ num_type_val_to_struct = policydbp->p_types.nprim;
+ len = sizeof(type_datum_t *) * num_type_val_to_struct;
+ type_val_to_struct = (type_datum_t **)malloc(len);
+ if (!type_val_to_struct) {
+ fprintf(stderr, "type_val_to_struct: out of memory\n");
+ exit(1);
+ }
+ memset(type_val_to_struct, 0, len);
+ hashtab_map(policydbp->p_types.table, type_val_to_struct_helper, NULL);
+
rewind(yyin);
policydb_lineno = 1;
source_file[0] = '\0';
--- checkpolicy-1.22/policy_scan.l 2005-02-17 23:59:23.000000000 +0900
+++ checkpolicy-1.22.extends.3rd/policy_scan.l 2005-03-23 08:31:47.000000000 +0900
@@ -68,6 +68,8 @@ TYPEALIAS |
typealias { return(TYPEALIAS); }
TYPEATTRIBUTE |
typeattribute { return(TYPEATTRIBUTE); }
+TYPEEXTENDS |
+typeextends { return(TYPEEXTENDS); }
TYPE |
type { return(TYPE); }
BOOL |
@@ -78,6 +80,8 @@ ELSE |
else { return(ELSE); }
ALIAS |
alias { return(ALIAS); }
+EXTENDS |
+extends { return(EXTENDS); }
ATTRIBUTE |
attribute { return(ATTRIBUTE); }
TYPE_TRANSITION |
@@ -211,7 +215,8 @@ H2 { return(H2); }
"." |
"]" |
"~" |
-"*" { return(yytext[0]); }
+"*" |
+"@" { return(yytext[0]); }
. { yywarn("unrecognized character");}
%%
int yyerror(char *msg)
--- checkpolicy-1.22/policy_parse.y 2005-02-17 23:59:23.000000000 +0900
+++ checkpolicy-1.22.extends.3rd/policy_parse.y 2005-03-23 09:11:42.000000000 +0900
@@ -19,6 +19,11 @@
* the Free Software Foundation, version 2.
*/
+/* Updated: KaiGai Kohei, <kaigai@ak.jp.nec.com>
+ * Added inherited type extensions and '@' prefix. (2005/03/21)
+ */
+
+
/* FLASK */
%{
@@ -72,8 +77,8 @@ static int define_category(void);
static int define_level(int range);
static int define_attrib(void);
static int define_typealias(void);
-static int define_typeattribute(void);
-static int define_type(int alias);
+static int define_typeattribute(int extends);
+static int define_type(int alias, int extends);
static int define_compute_type(int which);
static int define_te_avtab(int which);
static int define_role_types(void);
@@ -130,9 +135,11 @@ static int define_ipv6_node_context(void
%token ROLES
%token TYPEALIAS
%token TYPEATTRIBUTE
+%token TYPEEXTENDS
%token TYPE
%token TYPES
%token ALIAS
+%token EXTENDS
%token ATTRIBUTE
%token BOOL
%token IF
@@ -287,6 +294,7 @@ te_decl : attribute_def
| type_def
| typealias_def
| typeattribute_def
+ | typeextends_def
| bool_def
| transition_def
| range_trans_def
@@ -297,19 +305,28 @@ attribute_def : ATTRIBUTE iden
{ if (define_attrib()) return -1;}
;
type_def : TYPE identifier alias_def opt_attr_list ';'
- {if (define_type(1)) return -1;}
+ {if (define_type(1, 0)) return -1;}
| TYPE identifier opt_attr_list ';'
- {if (define_type(0)) return -1;}
+ {if (define_type(0, 0)) return -1;}
+ | TYPE identifier alias_def opt_extends_list ';'
+ {if (define_type(1, 1)) return -1;}
+ | TYPE identifier opt_extends_list ';'
+ {if (define_type(0, 1)) return -1;}
;
typealias_def : TYPEALIAS identifier alias_def ';'
{if (define_typealias()) return -1;}
;
typeattribute_def : TYPEATTRIBUTE identifier id_comma_list ';'
- {if (define_typeattribute()) return -1;}
+ {if (define_typeattribute(0)) return -1;}
+ ;
+typeextends_def : TYPEEXTENDS identifier EXTENDS id_comma_list ';'
+ {if (define_typeattribute(1)) return -1;}
;
opt_attr_list : ',' id_comma_list
|
;
+opt_extends_list : EXTENDS id_comma_list
+ ;
bool_def : BOOL identifier bool_val ';'
{if (define_bool()) return -1;}
;
@@ -511,13 +528,13 @@ cexpr_prim : U1 op U2
| R3 op { if (insert_separator(1)) return -1; } names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_XTARGET), $2);
if ($$ == 0) return -1; }
- | T1 op { if (insert_separator(1)) return -1; } names_push
+ | T1 op { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, $2);
if ($$ == 0) return -1; }
- | T2 op { if (insert_separator(1)) return -1; } names_push
+ | T2 op { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), $2);
if ($$ == 0) return -1; }
- | T3 op { if (insert_separator(1)) return -1; } names_push
+ | T3 op { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_XTARGET), $2);
if ($$ == 0) return -1; }
| SAMEUSER
@@ -532,10 +549,10 @@ cexpr_prim : U1 op U2
| ROLE role_mls_op
{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
if ($$ == 0) return -1; }
- | SOURCE TYPE { if (insert_separator(1)) return -1; } names_push
+ | SOURCE TYPE { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ);
if ($$ == 0) return -1; }
- | TARGET TYPE { if (insert_separator(1)) return -1; } names_push
+ | TARGET TYPE { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), CEXPR_EQ);
if ($$ == 0) return -1; }
| L1 role_mls_op L2
@@ -695,20 +712,27 @@ tilde : '~'
;
asterisk : '*'
;
-names : identifier
+atmark : '@'
+ ;
+type_identifier : IDENTIFIER
+ { if (insert_id(yytext, 0)) return -1; }
+ | atmark IDENTIFIER
+ { if (insert_id("@", 0) || insert_id(yytext, 0)) return -1; }
+ ;
+names : type_identifier
{ if (insert_separator(0)) return -1; }
| nested_id_set
{ if (insert_separator(0)) return -1; }
| asterisk
{ if (insert_id("*", 0)) return -1;
if (insert_separator(0)) return -1; }
- | tilde identifier
+ | tilde type_identifier
{ if (insert_id("~", 0)) return -1;
if (insert_separator(0)) return -1; }
| tilde nested_id_set
- { if (insert_id("~", 0)) return -1;
+ { if (insert_id("~", 0)) return -1;
if (insert_separator(0)) return -1; }
- | identifier '-' { if (insert_id("-", 0)) return -1; } identifier
+ | type_identifier '-' { if (insert_id("-", 0)) return -1; } type_identifier
{ if (insert_separator(0)) return -1; }
;
tilde_push : tilde
@@ -717,6 +741,19 @@ tilde_push : tilde
asterisk_push : asterisk
{ if (insert_id("*", 1)) return -1; }
;
+type_names_push : type_identifier_push
+ | '{' type_identifier_list_push '}'
+ | tilde_push type_identifier_push
+ | tilde_push '{' type_identifier_list_push '}'
+ ;
+type_identifier_list_push : type_identifier_push
+ | type_identifier_list_push type_identifier_push
+ ;
+type_identifier_push : IDENTIFIER
+ { if (insert_id(yytext,1)) return -1; }
+ | atmark IDENTIFIER
+ { if (insert_id(yytext,1)||insert_id("@",1)) return -1;}
+ ;
names_push : identifier_push
| '{' identifier_list_push '}'
| asterisk_push
@@ -736,7 +773,9 @@ nested_id_set : '{' nested_id_
;
nested_id_list : nested_id_element | nested_id_list nested_id_element
;
-nested_id_element : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set
+nested_id_element : type_identifier
+ | '-' { if (insert_id("-", 0)) return -1; } type_identifier
+ | nested_id_set
;
identifier : IDENTIFIER
{ if (insert_id(yytext,0)) return -1; }
@@ -1543,10 +1582,35 @@ static int define_typealias(void)
return 0;
}
-static int define_typeattribute(void)
+static int check_loop_inheritance(type_datum_t *td, int parent_typeval)
+{
+ type_datum_t *child;
+ int i;
+
+ /* attribute never have inheritance loop */
+ if (td->isattr)
+ return 0;
+
+ for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+ if (!ebitmap_get_bit(&td->types, i))
+ continue;
+ if ( parent_typeval - 1 == i )
+ return -1; /* Loop inheritance detected */
+ child = get_type(i+1);
+ if (!child) {
+ yyerror("BUG: unregistered type");
+ return -1;
+ }
+ if (check_loop_inheritance(child, parent_typeval))
+ return -1;
+ }
+ return 0;
+}
+
+static int define_typeattribute(int extends)
{
char *id;
- type_datum_t *t, *attr;
+ type_datum_t *t, *inherit;
if (pass == 2) {
while ((id = queue_remove(id_queue)))
@@ -1569,16 +1633,17 @@ static int define_typeattribute(void)
}
while ((id = queue_remove(id_queue))) {
- attr = hashtab_search(policydbp->p_types.table, id);
- if (!attr) {
- sprintf(errormsg, "attribute %s is not declared", id);
+ inherit = hashtab_search(policydbp->p_types.table, id);
+ if (!inherit) {
+ sprintf(errormsg, "%sattribute %s is not declared",
+ (extends ? "type/" : ""), id);
/* treat it as a fatal error */
yyerror(errormsg);
free(id);
return -1;
}
- if (!attr->isattr) {
+ if (!extends && !inherit->isattr) {
sprintf(errormsg, "%s is a type, not an attribute", id);
yyerror(errormsg);
free(id);
@@ -1587,7 +1652,12 @@ static int define_typeattribute(void)
free(id);
- if (ebitmap_set_bit(&attr->types, (t->value - 1), TRUE)) {
+ if (check_loop_inheritance(t, inherit->value)) {
+ yyerror("inheritance loop is detected");
+ return -1;
+ }
+
+ if (ebitmap_set_bit(&inherit->types, (t->value - 1), TRUE)) {
yyerror("out of memory");
return -1;
}
@@ -1596,10 +1666,10 @@ static int define_typeattribute(void)
return 0;
}
-static int define_type(int alias)
+static int define_type(int alias, int extends)
{
char *id;
- type_datum_t *datum, *aliasdatum, *attr;
+ type_datum_t *datum, *aliasdatum, *inherit;
int ret, newattr = 0;
@@ -1677,9 +1747,10 @@ static int define_type(int alias)
}
while ((id = queue_remove(id_queue))) {
- attr = hashtab_search(policydbp->p_types.table, id);
- if (!attr) {
- sprintf(errormsg, "attribute %s is not declared", id);
+ inherit = hashtab_search(policydbp->p_types.table, id);
+ if (!inherit) {
+ sprintf(errormsg, "%sattribute %s is not declared",
+ (extends)?"type/":"", id);
#if 1
/* treat it as a fatal error */
yyerror(errormsg);
@@ -1708,7 +1779,7 @@ static int define_type(int alias)
newattr = 0;
}
- if (!attr->isattr) {
+ if (!extends && !inherit->isattr) {
sprintf(errormsg, "%s is a type, not an attribute", id);
yyerror(errormsg);
return -1;
@@ -1717,7 +1788,7 @@ static int define_type(int alias)
if (!newattr)
free(id);
- ebitmap_set_bit(&attr->types, datum->value - 1, TRUE);
+ ebitmap_set_bit(&inherit->types, datum->value - 1, TRUE);
}
return 0;
@@ -1759,11 +1830,13 @@ static char *type_val_to_name(unsigned i
static int set_types(ebitmap_t *set,
ebitmap_t *negset,
+ ebitmap_t *inherit,
char *id,
int *add)
{
type_datum_t *t;
unsigned int i;
+ ebitmap_t temp;
if (strcmp(id, "*") == 0) {
/* set all types not in negset */
@@ -1788,10 +1861,16 @@ static int set_types(ebitmap_t *set,
}
if (strcmp(id, "-") == 0) {
- *add = 0;
+ *add &= 0xfffe; /* clear bit 0*/
+ free(id);
+ return 0;
+ }
+
+ if (strcmp(id, "@") == 0) {
+ *add |= 0x0002; /* set bit 1 */
free(id);
return 0;
- }
+ }
t = hashtab_search(policydbp->p_types.table, id);
if (!t) {
@@ -1800,42 +1879,28 @@ static int set_types(ebitmap_t *set,
free(id);
return -1;
}
+ if (inherit && ((*add)&0x0002)!=0 )
+ ebitmap_set_bit(inherit, t->value - 1, TRUE);
- if (t->isattr) {
- /* set or clear all types with this attribute,
- but do not set anything explicitly cleared previously */
- for (i = ebitmap_startbit(&t->types); i < ebitmap_length(&t->types); i++) {
- if (!ebitmap_get_bit(&t->types, i))
- continue;
- if (!(*add)) {
- ebitmap_set_bit(set, i, FALSE);
- ebitmap_set_bit(negset, i, TRUE);
- } else if (!ebitmap_get_bit(negset, i)) {
- ebitmap_set_bit(set, i, TRUE);
-#if VERBOSE
- } else {
- char *name = type_val_to_name(i+1);
- sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
- yywarn(errormsg);
-#endif
- }
- }
- } else {
- /* set or clear one type, but do not set anything
- explicitly cleared previously */
- if (!(*add)) {
- ebitmap_set_bit(set, t->value - 1, FALSE);
- ebitmap_set_bit(negset, t->value - 1, TRUE);
- } else if (!ebitmap_get_bit(negset, t->value - 1)) {
- ebitmap_set_bit(set, t->value - 1, TRUE);
+ ebitmap_init(&temp);
+ get_child_types(&temp, t, (*add)&0x0002);
+ for (i = ebitmap_startbit(&temp); i < ebitmap_length(&temp); i++) {
+ if (!ebitmap_get_bit(&temp, i))
+ continue;
+ if (!((*add)&0x0001)) {
+ ebitmap_set_bit(set, i, FALSE);
+ ebitmap_set_bit(negset, i, TRUE);
+ } else if (!ebitmap_get_bit(negset, i)) {
+ ebitmap_set_bit(set, i, TRUE);
#if VERBOSE
} else {
- sprintf(errormsg, "ignoring %s due to prior -%s", id, id);
+ char *name = type_val_to_name(i+1);
+ sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
yywarn(errormsg);
#endif
}
}
-
+ ebitmap_destroy(&temp);
free(id);
*add = 1;
return 0;
@@ -1872,14 +1937,14 @@ static int define_compute_type(int which
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -2012,14 +2077,14 @@ static cond_av_list_t *define_cond_compu
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, NULL, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
@@ -2419,9 +2484,10 @@ static cond_av_list_t *define_cond_te_av
cond_av_list_t *sub_list, *final_list, *tail;
class_datum_t *cladatum;
perm_datum_t *perdatum;
- ebitmap_t stypes, ttypes, tclasses, negset;
+ type_datum_t *typedatum;
+ ebitmap_t stypes, ttypes, tclasses, temp, inherit, negset;
access_vector_t *avp;
- int i, j, hiclass, self = 0, add = 1;
+ int i, j, k, hiclass, self = 0, add = 1;
int suppress = 0;
if (pass == 1) {
@@ -2439,10 +2505,11 @@ static cond_av_list_t *define_cond_te_av
ebitmap_init(&stypes);
ebitmap_init(&ttypes);
ebitmap_init(&tclasses);
+ ebitmap_init(&inherit);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, &inherit, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
@@ -2453,7 +2520,7 @@ static cond_av_list_t *define_cond_te_av
self = 1;
continue;
}
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
@@ -2542,19 +2609,36 @@ static cond_av_list_t *define_cond_te_av
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
if (!ebitmap_get_bit(&stypes, i))
continue;
- if (self) {
- if ((sub_list = cond_te_avtab_helper(which, i, i, &tclasses, avp )) == COND_ERR)
- return COND_ERR;
- if (final_list) {
- tail->next = sub_list;
- while (tail->next != NULL)
- tail = tail->next;
- } else {
- final_list = sub_list;
- tail = final_list;
- while (tail->next != NULL)
- tail = tail->next;
+ typedatum = get_type(i+1);
+ if (!typedatum)
+ return COND_ERR;
+ ebitmap_init(&temp);
+ /* If the source type is given with '@' prefix,
+ 'self' also includes own child types. */
+ get_child_types(&temp, typedatum, ebitmap_get_bit(&inherit,i));
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if(!ebitmap_get_bit(&temp, j))
+ continue;
+ for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+ if(!ebitmap_get_bit(&temp, k))
+ continue;
+ sub_list = cond_te_avtab_helper(which, j, k, &tclasses, avp);
+ if (sub_list==COND_ERR) {
+ ebitmap_destroy(&temp);
+ return COND_ERR;
+ }
+ if (final_list) {
+ tail->next = sub_list;
+ while (tail->next != NULL)
+ tail = tail->next;
+ } else {
+ final_list = sub_list;
+ tail = final_list;
+ while (tail->next != NULL)
+ tail = tail->next;
+ }
}
+ ebitmap_destroy(&temp);
}
}
}
@@ -2595,9 +2679,10 @@ static int define_te_avtab(int which)
char *id;
class_datum_t *cladatum;
perm_datum_t *perdatum;
- ebitmap_t stypes, ttypes, tclasses, negset;
+ type_datum_t *typedatum;
+ ebitmap_t stypes, ttypes, tclasses, temp, inherit, negset;
access_vector_t *avp;
- unsigned int i, j, hiclass;
+ unsigned int i, j, k, hiclass;
int self = 0, add = 1;
te_assert_t *newassert;
int suppress = 0;
@@ -2617,10 +2702,11 @@ static int define_te_avtab(int which)
ebitmap_init(&stypes);
ebitmap_init(&ttypes);
ebitmap_init(&tclasses);
+ ebitmap_init(&inherit);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, &inherit, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -2631,7 +2717,7 @@ static int define_te_avtab(int which)
self = 1;
continue;
}
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -2723,6 +2809,7 @@ static int define_te_avtab(int which)
newassert->stypes = stypes;
newassert->ttypes = ttypes;
newassert->tclasses = tclasses;
+ newassert->inherit = inherit;
newassert->self = self;
newassert->avp = avp;
newassert->line = policydb_lineno;
@@ -2735,8 +2822,26 @@ static int define_te_avtab(int which)
if (!ebitmap_get_bit(&stypes, i))
continue;
if (self) {
- if (te_avtab_helper(which, i, i, &tclasses, avp))
+ typedatum = get_type(i+1);
+ if (!typedatum)
return -1;
+ ebitmap_init(&temp);
+ /* If the source type is given with '@' prefix,
+ 'self' means own child types. */
+ get_child_types(&temp, typedatum, ebitmap_get_bit(&inherit, i));
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if (!ebitmap_get_bit(&temp, j))
+ continue;
+ for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+ if (!ebitmap_get_bit(&temp, k))
+ continue;
+ if (te_avtab_helper(which, j, k, &tclasses, avp)) {
+ ebitmap_destroy(&temp);
+ return -1;
+ }
+ }
+ }
+ ebitmap_destroy(&temp);
}
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
if (!ebitmap_get_bit(&ttypes, j))
@@ -2827,7 +2932,7 @@ static int define_role_types(void)
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&role->types, &negset, id, &add))
+ if (set_types(&role->types, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -3042,7 +3147,7 @@ static int define_role_trans(void)
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&types, &negset, id, &add))
+ if (set_types(&types, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -3467,7 +3572,7 @@ static uintptr_t
}
val = role->value;
} else if (expr->attr & CEXPR_TYPE) {
- if (set_types(&expr->names, &negset, id, &add)) {
+ if (set_types(&expr->names, &negset, NULL, id, &add)) {
free(expr);
return 0;
}
@@ -4903,14 +5008,14 @@ static int define_range_trans(void)
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&doms, &negset, id, &add))
+ if (set_types(&doms, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&types, &negset, id, &add))
+ if (set_types(&types, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-23 8:17 ` Kaigai Kohei
@ 2005-03-23 13:56 ` Stephen Smalley
2005-04-16 7:31 ` KaiGai Kohei
2005-03-24 11:06 ` Luke Kenneth Casson Leighton
1 sibling, 1 reply; 58+ messages in thread
From: Stephen Smalley @ 2005-03-23 13:56 UTC (permalink / raw)
To: Kaigai Kohei; +Cc: KaiGai Kohei, SELinux Mail List
On Wed, 2005-03-23 at 17:17 +0900, Kaigai Kohei wrote:
> The attached (3rd) patch implements TYPEEXTENDS statement in addition
> to the latest patch. Because TYPE ... EXTENDS statements can not handle
> forwarding loopup, TYPEEXTENDS statement is necessary to represent
> inheritance-relationship not to depend on the definition placement.
>
> TYPEEXTENDS <type-name> EXTENDS <type/attr>, <type/attr>, ... ;
>
> (*) <type-name> and <type/attr> must have been defined.
> This is almost the same as TYPEATTRIBUTE.
<snip>
> I tried to modify the Fedora-C3's strict policy for quick testing,
> and represent a unified file type of HTTPd/Samba/FTPd.
>
> I intend to access /var/www/ftp via HTTP and FTP, /var/www/samba via HTTP and Samba.
> The following configuration was necessary for this purpose.
>
> BTW, since any macros (such as apache) were so complex for me, the following
> configuration may be insufficiency in a precise sense.
> But it's easily understandable as a configuration sample for real application,
> I think.
Thanks for the additional patch and the example. I'd like to encourage
people on the list who are actively writing policies to look at this
language extension and example and comment on whether they think it
would be helpful to them.
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-22 13:53 ` Karl MacMillan
@ 2005-03-24 11:04 ` Luke Kenneth Casson Leighton
2005-03-24 12:31 ` Kaigai Kohei
2005-03-24 22:27 ` Luke Kenneth Casson Leighton
0 siblings, 2 replies; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-24 11:04 UTC (permalink / raw)
To: Karl MacMillan
Cc: 'Stephen Smalley', 'Kaigai Kohei',
'KaiGai Kohei', 'SELinux Mail List', selinux-dev
On Tue, Mar 22, 2005 at 08:53:28AM -0500, Karl MacMillan wrote:
> > -----Original Message-----
> > From: Luke Kenneth Casson Leighton [mailto:lkcl@lkcl.net]
> > Sent: Monday, March 21, 2005 7:15 PM
> <snip>
> > >
> > > First, you missed the switch to the @ being required in order to
> > > inherit permissions through extends - making that syntax,
> > as far as I
> > > can tell, the same as what you are suggesting.
> >
> > i understood it to be the other way round - that the @ is
> > required to _not_ allow a permission to be inherited through extends.
> >
> >
>
> Like I said - it switched part way through the discussion.
okay, i must have missed that.
... but, after a couple of days' thought, i don't believe
that what i am suggesting is anything anywhere near the @
syntax, and it is in fact in response to some comments by
stephen [where he mentioned that it would be better to split
domains up further using macros than it would be to use
this inheritance system with some modifications suggested
by me, so off i went to think of some better modifications -
clarification below]
> > > Next, my objection is that there is only one subset of
> > permissions -
> > > there is no way to have user_ftp_t inherit one set of
> > permissions from
> > > user_t and user_httpd_t inherit another set of permissions from
> > > user_t.
> >
> > note syntax in example [copied from above]:
> >
> > > > some_macro (`
> > > > inheritable($1_ftp_t, parent_class2_t) {
> > ^^^^^^^^ ^^^^^^^^^^^^^^^
> > > >
> > > > allow ....;
> > > >
> > > > }
> >
> > so, to link this with your examples above, let's express this in
> > "inheritable() { ... }" syntax:
> >
> > some_macro (`
> > inheritable($1_ftp_t, $1_httpd_t) {
> > allow ....;
> > }
> > inheritable($1_ftp_t) {
> > allow ....;
> > }
> > inheritable($1_httpd_t) {
> > allow ....;
> > }
> > allow ....;
> > }
> >
> > ')
> >
> > make sense?
> >
>
> I guess I don't understand how your proposed syntax works. What does it mean
> when there are two types?
that one set of permissions is inheritable via "extends"
and other sets are not.
the reason why i am suggesting this syntax is because stephen said that
it would not be okay to split macros down into sub-macro in order to
inherit/extend "subsets" of a domain.
e.g. if you do user_ftp_t extends user_t where you have already
declared some_macro(user) then it ends up inheriting ONLY those
blocks of permissions containing "user_ftp_t" inside "inheritable { }"
braces.
... so, after some thought, however, i believe we may be talking
about two separate issues.
the "inheritable" syntax i suggest above is a way to inherit SUBSETS of
a domain, without disrupting the existing policy source too much (which
i interpreted stephen's comments to mean)
so, correct me if i am wrong, but the "@" syntax doesn't actually STOP
something from being "extended", it just means that a different domain
is inherited, yes?
and your original question was: when you use A "extends" B and C
"extends" B, and B contains "@"s, how do you potentially make A
ignore the "@" but C _not_ ignore the "@"?
if that was your original question, then that's easy: you use a syntax
@(A) or @(A,Z,Y,X)
I BELIEVE that the "inheritable" syntax above could be added as an
enhancement to the existing proposed "extends" scheme, WITHOUT
disrupting or having anything to do with the "@" syntax.
the only question is: do you _want_ to use "inheritable" instead of
splitting macros down into sub-macros to achieve the same end-result?
which is simpler?
which is easier to understand?
does the "inheritable" syntax cause any potential disruption/confusion
(beyond what the @ syntax already does if you ask me!!!!)
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-23 8:17 ` Kaigai Kohei
2005-03-23 13:56 ` Stephen Smalley
@ 2005-03-24 11:06 ` Luke Kenneth Casson Leighton
2005-03-24 12:34 ` Kaigai Kohei
1 sibling, 1 reply; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-24 11:06 UTC (permalink / raw)
To: Kaigai Kohei; +Cc: Stephen Smalley, KaiGai Kohei, SELinux Mail List
On Wed, Mar 23, 2005 at 05:17:57PM +0900, Kaigai Kohei wrote:
kaigai,
i love it. i see where it's going.
i just don't get it yet.
:)
> Hi,
>
> The attached (3rd) patch implements TYPEEXTENDS statement in addition
> to the latest patch. Because TYPE ... EXTENDS statements can not handle
> forwarding loopup, TYPEEXTENDS statement is necessary to represent
> inheritance-relationship not to depend on the definition placement.
>
> TYPEEXTENDS <type-name> EXTENDS <type/attr>, <type/attr>, ... ;
>
> (*) <type-name> and <type/attr> must have been defined.
> This is almost the same as TYPEATTRIBUTE.
> # Access Samba shares.
> -allow smbd_t samba_share_t:dir create_dir_perms;
> -allow smbd_t samba_share_t:file create_file_perms;
> +attribute samba_share_path;
> +allow smbd_t samba_share_path:dir {getattr search};
> +allow smbd_t @samba_share_t:dir create_dir_perms;
> +allow smbd_t @samba_share_t:file create_file_perms;
>
> o And, private additional configuration is as follows:
> --- /dev/null 2005-03-22 18:46:01.562514976 -0500
> +++ policy.kaigai/inaddition.te 2005-03-23 04:06:49.576548144 -0500
> @@ -0,0 +1,7 @@
> +# necessity for access path
> +typeattribute var_t ftp_content_path, samba_share_path;
> +typeattribute httpd_sys_content_t ftp_content_path, samba_share_path;
> +# definition of unified file type
> +type httpd_ftp_t extends httpd_sys_content_t, ftp_content_t;
> +type httpd_samba_t extends httpd_sys_content_t, samba_share_t;
... what's the difference between attribute and typeattribute?
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-24 11:04 ` Luke Kenneth Casson Leighton
@ 2005-03-24 12:31 ` Kaigai Kohei
2005-03-24 22:19 ` Luke Kenneth Casson Leighton
2005-03-24 22:27 ` Luke Kenneth Casson Leighton
1 sibling, 1 reply; 58+ messages in thread
From: Kaigai Kohei @ 2005-03-24 12:31 UTC (permalink / raw)
To: Luke Kenneth Casson Leighton
Cc: Karl MacMillan, 'Stephen Smalley', 'KaiGai Kohei',
'SELinux Mail List', selinux-dev
Hello,
> and your original question was: when you use A "extends" B and C
> "extends" B, and B contains "@"s, how do you potentially make A
> ignore the "@" but C _not_ ignore the "@"?
That means as follows, doesn't it ?
<type B>
+ <type A>
+ <type C>
"allow foo_t @B - @C:file getattr ;" is rolled out to
"allow foo_t {B A}:file getattr ;" as you want.
> if that was your original question, then that's easy: you use a syntax
> @(A) or @(A,Z,Y,X)
I also thought such statements, but don't implement it.
Indeed, implementing "@{A B C D}" is easy.
But "{A B @{C D}}" will be desired next, if we can represent such statement.
It's difficult to handle the nested statement in current checkpolicy implementation.
(we need much efforts to this, if my understanding is not mistake.)
Please look the implementation of '~', is similar to '@' processing.
Thanks,
--
Linux Promotion Center, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-24 11:06 ` Luke Kenneth Casson Leighton
@ 2005-03-24 12:34 ` Kaigai Kohei
0 siblings, 0 replies; 58+ messages in thread
From: Kaigai Kohei @ 2005-03-24 12:34 UTC (permalink / raw)
To: Luke Kenneth Casson Leighton
Cc: Stephen Smalley, KaiGai Kohei, SELinux Mail List
Hello,
>>o And, private additional configuration is as follows:
>>--- /dev/null 2005-03-22 18:46:01.562514976 -0500
>>+++ policy.kaigai/inaddition.te 2005-03-23 04:06:49.576548144 -0500
>>@@ -0,0 +1,7 @@
>>+# necessity for access path
>>+typeattribute var_t ftp_content_path, samba_share_path;
>>+typeattribute httpd_sys_content_t ftp_content_path, samba_share_path;
>>+# definition of unified file type
>>+type httpd_ftp_t extends httpd_sys_content_t, ftp_content_t;
>>+type httpd_samba_t extends httpd_sys_content_t, samba_share_t;
>
> ... what's the difference between attribute and typeattribute?
There are two differences between attribute and inherited type.
1) We can use source types directly such as httpd_sys_content_t.
If these are declared as attribute, we have to define one more
type which is attached those attributes.
2) When httpd_samba_t has a child type labeled httpd_samba_ftp_t and accessed
via Apache, Samba and FTP, the definition of type needs to inherit only
httpd_samba_t and ftp_content_t as an additional type.
If those are defined as attributes, httpd_samba_ftp_t have to inherit
all of these attributes.
The benefit of EXTENDS comparing with ATTRIBUTE may be uncertainness
for two-layer structure, but it's obviously for multi-layer structure,I think.
e.g,
When we try to define /home/foo labeled foo_home_t accessed via Samba and FTP,
and /home/foo/public_html labeled foo_public_html_t accessed vis Apache in addition,
we must append all attributes for each type, if thoes are defined as attribute.
If we can use EXTENDS statements, foo_public_html_t only have to inherit foo_home_t
and pre-defined type for HTML contents.
Thanks,
--
Linux Promotion Center, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-24 12:31 ` Kaigai Kohei
@ 2005-03-24 22:19 ` Luke Kenneth Casson Leighton
0 siblings, 0 replies; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-24 22:19 UTC (permalink / raw)
To: Kaigai Kohei
Cc: Karl MacMillan, 'Stephen Smalley', 'KaiGai Kohei',
'SELinux Mail List', selinux-dev
On Thu, Mar 24, 2005 at 09:31:41PM +0900, Kaigai Kohei wrote:
> Hello,
>
> > and your original question was: when you use A "extends" B and C
> > "extends" B, and B contains "@"s, how do you potentially make A
> > ignore the "@" but C _not_ ignore the "@"?
>
> That means as follows, doesn't it ?
> <type B>
> + <type A>
> + <type C>
yes.
> "allow foo_t @B - @C:file getattr ;" is rolled out to
> "allow foo_t {B A}:file getattr ;" as you want.
ah ha!
great.
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-24 11:04 ` Luke Kenneth Casson Leighton
2005-03-24 12:31 ` Kaigai Kohei
@ 2005-03-24 22:27 ` Luke Kenneth Casson Leighton
1 sibling, 0 replies; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-03-24 22:27 UTC (permalink / raw)
To: Karl MacMillan, 'Stephen Smalley', 'Kaigai Kohei',
'KaiGai Kohei', 'SELinux Mail List', selinux-dev
On Thu, Mar 24, 2005 at 11:04:38AM +0000, Luke Kenneth Casson Leighton wrote:
> On Tue, Mar 22, 2005 at 08:53:28AM -0500, Karl MacMillan wrote:
>
> > > -----Original Message-----
> > > From: Luke Kenneth Casson Leighton [mailto:lkcl@lkcl.net]
> > > Sent: Monday, March 21, 2005 7:15 PM
> > <snip>
> > > >
> > > > First, you missed the switch to the @ being required in order to
> > > > inherit permissions through extends - making that syntax,
> > > as far as I
> > > > can tell, the same as what you are suggesting.
> > >
> > > i understood it to be the other way round - that the @ is
> > > required to _not_ allow a permission to be inherited through extends.
> > >
> > >
> >
> > Like I said - it switched part way through the discussion.
>
> okay, i must have missed that.
>
> ... but, after a couple of days' thought, i don't believe
> that what i am suggesting is anything anywhere near the @
> syntax, and it is in fact in response to some comments by
> stephen [where he mentioned that it would be better to split
> domains up further using macros than it would be to use
> this inheritance system with some modifications suggested
> by me, so off i went to think of some better modifications -
> clarification below]
>
>
> > > > Next, my objection is that there is only one subset of
> > > permissions -
> > > > there is no way to have user_ftp_t inherit one set of
> > > permissions from
> > > > user_t and user_httpd_t inherit another set of permissions from
> > > > user_t.
> > >
> > > note syntax in example [copied from above]:
> > >
> > > > > some_macro (`
> > > > > inheritable($1_ftp_t, parent_class2_t) {
> > > ^^^^^^^^ ^^^^^^^^^^^^^^^
> > > > >
> > > > > allow ....;
> > > > >
> > > > > }
> > >
> > > so, to link this with your examples above, let's express this in
> > > "inheritable() { ... }" syntax:
> > >
> > > some_macro (`
> > > inheritable($1_ftp_t, $1_httpd_t) {
> > > allow ....;
> > > }
> > > inheritable($1_ftp_t) {
> > > allow ....;
> > > }
> > > inheritable($1_httpd_t) {
> > > allow ....;
> > > }
> > > allow ....;
> > > }
> > >
> > > ')
> > >
> > > make sense?
> > >
> >
> > I guess I don't understand how your proposed syntax works. What does it mean
> > when there are two types?
sorry - i mis-read your question.
when there are two types, it means: when you use
some_macro(user) and you then declare type user_httpd_t it
gets all the stuff where user_httpd_t occurs in _any_ inheritable()
wrap and when you declare user_ftp_t, likewise.
inheritable($1_ftp_t, $1_httpd_t) {
allow A;
}
inheritable($1_ftp_t) {
allow B;
}
inheritable($1_httpd_t) {
allow C;
}
allow D;
therefore:
user_httpd_t comprises allow A and allow C
user_ftp_t comprises allow A and allow B,
user_t comprises allow A B C _and_ D.
because D is not inside an inheritable() wrap, it never gets
inherited by "extends" syntax.
hence, this could be viewed as a simplification of having to
split some_macro into ... mmm... _four (!) separate sub-macros
one each covering the permissions allow A, allow B, allow C
and allow D:
some_macro ('
some_macro_A($1) # representing inheritable A group above
some_macro_B($1) # ... etc.
some_macro_C($1)
some_macro_D($1)
')
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-15 11:50 ` KaiGai Kohei
2005-03-15 14:42 ` Stephen Smalley
@ 2005-04-06 12:49 ` Russell Coker
2005-04-06 14:50 ` KaiGai Kohei
1 sibling, 1 reply; 58+ messages in thread
From: Russell Coker @ 2005-04-06 12:49 UTC (permalink / raw)
To: KaiGai Kohei; +Cc: SELinux Mail List, kaigai
On Tuesday 15 March 2005 22:50, KaiGai Kohei <kaigai@kaigai.gr.jp> wrote:
> Does 'unifying file type' means as follows ?
> e.g)
> /var ... var_t
> /var/lib ... var_lib_t extends var_t
> /var/log ... var_log_t extends var_t
> /var/log/message ... var_log_message_t extends var_log_t
> Of course, such a usage is also possible.
This is an example of how not to do it.
Many domains need search access to /var. Most of them should not be granted
any access to /var/log, but your example would have them granted search
access to /var/log as var_log_t inherits from var_t.
Many domains access /var/log (probably more than we desire but that's a
separate issue - the fact that user_ssh_t is granted read access to files of
type var_log_t seems like a policy bug to me). /var/log/message may have
data that is more secret than the other files/directories labeled as
var_log_t, and we don't want user_ssh_t to read it.
On Wednesday 16 March 2005 15:42, Kaigai Kohei <kaigai@ak.jp.nec.com> wrote:
> Indeed, a user_t process can take permissions of a user_ext_t process
> through ptrace. It was blid spot for me.
To address this you could have user_t inherit from a virtual base type
user_base_t which doesn't have ptrace access.
> I have an idea that ALLOW statement is added an new option
> For example:
> ALLOW @user_t @user_t:process {ptrace};
> ALLOW user_t @user_t:process {transition};
I don't like that idea. Tracking when the '@' symbol should be used will be
beyond the skill of most people who write policy. Then there is the issue of
someone writing a domain with the idea that it will never be used for
inheritance but then having it used for inheritance later. If the inherited
domain has it's policy in the public repository then things can get fixed,
but if someone inherits a domain for their own private use then they could
get surprised by a policy update that grants some access they didn't expect
because the upstream policy developers didn't plan for inheritance and didn't
use the '@' symbol.
Your message on the 23rd of March seems to be OK in terms of access, but I
doubt that the '@' operator will result in good policy.
About a year ago I was involved in some discussions about these issues, and
one of the major factors was how to deal with user_t/user_r/user_ssh_t and
other_t/other_r/other_ssh_t type inheritance. One of the NSA guys asked me
to write up a proposal for how to do this. After thinking about it for a
year I haven't devised a good answer. If your work can result in a solution
to this problem then I'm sure that everyone will be willing to accept some
trade-offs. But currently I am not convinced that the benefits outweigh the
costs of this.
--
http://www.coker.com.au/selinux/ My NSA Security Enhanced Linux packages
http://www.coker.com.au/bonnie++/ Bonnie++ hard drive benchmark
http://www.coker.com.au/postal/ Postal SMTP/POP benchmark
http://www.coker.com.au/~russell/ My home page
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-04-06 12:49 ` Russell Coker
@ 2005-04-06 14:50 ` KaiGai Kohei
2005-04-06 15:30 ` Russell Coker
2005-04-06 17:55 ` Luke Kenneth Casson Leighton
0 siblings, 2 replies; 58+ messages in thread
From: KaiGai Kohei @ 2005-04-06 14:50 UTC (permalink / raw)
To: russell; +Cc: SELinux Mail List, kaigai
Hello, Thanks for your comments.
Russell Coker wrote:
> On Tuesday 15 March 2005 22:50, KaiGai Kohei <kaigai@kaigai.gr.jp> wrote:
>
>>Does 'unifying file type' means as follows ?
>>e.g)
>> /var ... var_t
>> /var/lib ... var_lib_t extends var_t
>> /var/log ... var_log_t extends var_t
>> /var/log/message ... var_log_message_t extends var_log_t
>>Of course, such a usage is also possible.
>
>
> This is an example of how not to do it.
>
> Many domains need search access to /var. Most of them should not be granted
> any access to /var/log, but your example would have them granted search
> access to /var/log as var_log_t inherits from var_t.
>
> Many domains access /var/log (probably more than we desire but that's a
> separate issue - the fact that user_ssh_t is granted read access to files of
> type var_log_t seems like a policy bug to me). /var/log/message may have
> data that is more secret than the other files/directories labeled as
> var_log_t, and we don't want user_ssh_t to read it.
Yes, you are right.
The above /var/XXX is not appropriate for example, I also think now.
>>I have an idea that ALLOW statement is added an new option
>>For example:
>> ALLOW @user_t @user_t:process {ptrace};
>> ALLOW user_t @user_t:process {transition};
>
>
> I don't like that idea. Tracking when the '@' symbol should be used will be
> beyond the skill of most people who write policy. Then there is the issue of
> someone writing a domain with the idea that it will never be used for
> inheritance but then having it used for inheritance later. If the inherited
> domain has it's policy in the public repository then things can get fixed,
> but if someone inherits a domain for their own private use then they could
> get surprised by a policy update that grants some access they didn't expect
> because the upstream policy developers didn't plan for inheritance and didn't
> use the '@' symbol.
I think that the required skill for tracking the security policy with inherited type
is same as one for the security policy writen with attributes.
Tracking difficulty will not change between the legacy statement and new one.
But I understand your concern about an inherited domain.
My original idea was started from 'inherited domain', but I noticed
the worth of 'unified type' via this discussion.
This statement can't ban an 'inherited domain', but it will not be
significant requirement for using '@' prefix for any domain in upstream policy.
It's more importantly that the permissions of Apache/Samba/FTPd/etc... to
its contents files/directories will be granted with '@' prefix for extensiton
on end-user configuration.
> Your message on the 23rd of March seems to be OK in terms of access, but I
> doubt that the '@' operator will result in good policy.
I think that '@' prefix and inheritable type can reduce the amount of description
and redundancy. Indeed, it's not resolve all of the difficulty for policy description.
> About a year ago I was involved in some discussions about these issues, and
> one of the major factors was how to deal with user_t/user_r/user_ssh_t and
> other_t/other_r/other_ssh_t type inheritance. One of the NSA guys asked me
> to write up a proposal for how to do this. After thinking about it for a
> year I haven't devised a good answer. If your work can result in a solution
> to this problem then I'm sure that everyone will be willing to accept some
> trade-offs. But currently I am not convinced that the benefits outweigh the
> costs of this.
Does the example of user_t/user_r/user_ssh_t mean 'inherited domain'?
It has not been a significant issue yet, I think.
I think it's enough benefit to create a new type which can be accessed from
multi domains. (e.g Apache & FTPd shared directory)
Thanks,
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-04-06 14:50 ` KaiGai Kohei
@ 2005-04-06 15:30 ` Russell Coker
2005-04-06 18:23 ` Jim McCullough
2005-04-07 2:16 ` Kaigai Kohei
2005-04-06 17:55 ` Luke Kenneth Casson Leighton
1 sibling, 2 replies; 58+ messages in thread
From: Russell Coker @ 2005-04-06 15:30 UTC (permalink / raw)
To: KaiGai Kohei; +Cc: SELinux Mail List, kaigai
On Thursday 07 April 2005 00:50, KaiGai Kohei <kaigai@kaigai.gr.jp> wrote:
> > I don't like that idea. Tracking when the '@' symbol should be used will
> > be beyond the skill of most people who write policy. Then there is the
> > issue of someone writing a domain with the idea that it will never be
> > used for inheritance but then having it used for inheritance later. If
> > the inherited domain has it's policy in the public repository then things
> > can get fixed, but if someone inherits a domain for their own private use
> > then they could get surprised by a policy update that grants some access
> > they didn't expect because the upstream policy developers didn't plan for
> > inheritance and didn't use the '@' symbol.
>
> I think that the required skill for tracking the security policy with
> inherited type is same as one for the security policy writen with
> attributes.
When inspecting policy to determine it's operation you can see a list of
attributes on a type declaration and know that each applies to the type.
With inheritance as you describe you have exclusion rules such that you don't
necessarily know that domain user_foo_t can access bar_t just because user_t
can access bar_t and user_foo_t inherits.
If we want to make a change to the inheritance it doesn't change the access
granted to just one domain or type but instead it operates on an unknown
number of domains/types.
> > About a year ago I was involved in some discussions about these issues,
> > and one of the major factors was how to deal with
> > user_t/user_r/user_ssh_t and other_t/other_r/other_ssh_t type
> > inheritance. One of the NSA guys asked me to write up a proposal for how
> > to do this. After thinking about it for a year I haven't devised a good
> > answer. If your work can result in a solution to this problem then I'm
> > sure that everyone will be willing to accept some trade-offs. But
> > currently I am not convinced that the benefits outweigh the costs of
> > this.
>
> Does the example of user_t/user_r/user_ssh_t mean 'inherited domain'?
> It has not been a significant issue yet, I think.
> I think it's enough benefit to create a new type which can be accessed from
> multi domains. (e.g Apache & FTPd shared directory)
It does mean inherited domain.
I want to write policy such that someone can load a binary policy module for a
new user role professor_r which then automatically creates the domain
professor_foo_t because the base policy has appropriate statements that are
equivalent in functionality to the macros we currently use in macros/programs
for such things.
--
http://www.coker.com.au/selinux/ My NSA Security Enhanced Linux packages
http://www.coker.com.au/bonnie++/ Bonnie++ hard drive benchmark
http://www.coker.com.au/postal/ Postal SMTP/POP benchmark
http://www.coker.com.au/~russell/ My home page
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-04-06 14:50 ` KaiGai Kohei
2005-04-06 15:30 ` Russell Coker
@ 2005-04-06 17:55 ` Luke Kenneth Casson Leighton
1 sibling, 0 replies; 58+ messages in thread
From: Luke Kenneth Casson Leighton @ 2005-04-06 17:55 UTC (permalink / raw)
To: KaiGai Kohei; +Cc: russell, SELinux Mail List, kaigai
On Wed, Apr 06, 2005 at 11:50:45PM +0900, KaiGai Kohei wrote:
> But I understand your concern about an inherited domain.
> My original idea was started from 'inherited domain', but I noticed
> the worth of 'unified type' via this discussion.
>
> This statement can't ban an 'inherited domain', but it will not be
that's the reason why i suggested the inheritable(...) { } syntax.
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-04-06 15:30 ` Russell Coker
@ 2005-04-06 18:23 ` Jim McCullough
2005-04-07 2:16 ` Kaigai Kohei
1 sibling, 0 replies; 58+ messages in thread
From: Jim McCullough @ 2005-04-06 18:23 UTC (permalink / raw)
To: russell; +Cc: KaiGai Kohei, SELinux Mail List, kaigai
In regards to the multiple applications access /var/log and the macros
in use. With the current growth of the project, I see some future
issues where we might want to consider branching files under /var/log
to different policy contexts. This might help prevent applications
like ssh or apache from reading /var/log/messages. An idea would be
specification on common applications to restrict them withing
subdirectories for the applications specific. Debian Sarge & FC3 both
put httpd logs in a subdirectory under /var/log and can be restricted
in a manner to just those directories for access under /var/log.
Just a thought on future planning. I personally prefer a separate log
for any application that accesses /var/log for writing purposes. IE.
sshd has /var/log/sshd, while ftp has /var/log/ftpd/, and so forth.
Under a server that handles multiple domains, it makes life much
easier to maintain the log files for tracking user loads by the
individual client.
--
Jim McCullough
On Apr 6, 2005 11:30 AM, Russell Coker <russell@coker.com.au> wrote:
> On Thursday 07 April 2005 00:50, KaiGai Kohei <kaigai@kaigai.gr.jp> wrote:
> > > I don't like that idea. Tracking when the '@' symbol should be used will
> > > be beyond the skill of most people who write policy. Then there is the
> > > issue of someone writing a domain with the idea that it will never be
> > > used for inheritance but then having it used for inheritance later. If
> > > the inherited domain has it's policy in the public repository then things
> > > can get fixed, but if someone inherits a domain for their own private use
> > > then they could get surprised by a policy update that grants some access
> > > they didn't expect because the upstream policy developers didn't plan for
> > > inheritance and didn't use the '@' symbol.
> >
> > I think that the required skill for tracking the security policy with
> > inherited type is same as one for the security policy writen with
> > attributes.
>
> When inspecting policy to determine it's operation you can see a list of
> attributes on a type declaration and know that each applies to the type.
>
> With inheritance as you describe you have exclusion rules such that you don't
> necessarily know that domain user_foo_t can access bar_t just because user_t
> can access bar_t and user_foo_t inherits.
>
> If we want to make a change to the inheritance it doesn't change the access
> granted to just one domain or type but instead it operates on an unknown
> number of domains/types.
>
> > > About a year ago I was involved in some discussions about these issues,
> > > and one of the major factors was how to deal with
> > > user_t/user_r/user_ssh_t and other_t/other_r/other_ssh_t type
> > > inheritance. One of the NSA guys asked me to write up a proposal for how
> > > to do this. After thinking about it for a year I haven't devised a good
> > > answer. If your work can result in a solution to this problem then I'm
> > > sure that everyone will be willing to accept some trade-offs. But
> > > currently I am not convinced that the benefits outweigh the costs of
> > > this.
> >
> > Does the example of user_t/user_r/user_ssh_t mean 'inherited domain'?
> > It has not been a significant issue yet, I think.
> > I think it's enough benefit to create a new type which can be accessed from
> > multi domains. (e.g Apache & FTPd shared directory)
>
> It does mean inherited domain.
>
> I want to write policy such that someone can load a binary policy module for a
> new user role professor_r which then automatically creates the domain
> professor_foo_t because the base policy has appropriate statements that are
> equivalent in functionality to the macros we currently use in macros/programs
> for such things.
>
> --
> http://www.coker.com.au/selinux/ My NSA Security Enhanced Linux packages
> http://www.coker.com.au/bonnie++/ Bonnie++ hard drive benchmark
> http://www.coker.com.au/postal/ Postal SMTP/POP benchmark
> http://www.coker.com.au/~russell/ My home page
>
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-04-06 15:30 ` Russell Coker
2005-04-06 18:23 ` Jim McCullough
@ 2005-04-07 2:16 ` Kaigai Kohei
1 sibling, 0 replies; 58+ messages in thread
From: Kaigai Kohei @ 2005-04-07 2:16 UTC (permalink / raw)
To: russell; +Cc: KaiGai Kohei, SELinux Mail List
Hello,
>>I think that the required skill for tracking the security policy with
>>inherited type is same as one for the security policy writen with
>>attributes.
>
>
> When inspecting policy to determine it's operation you can see a list of
> attributes on a type declaration and know that each applies to the type.
>
> With inheritance as you describe you have exclusion rules such that you don't
> necessarily know that domain user_foo_t can access bar_t just because user_t
> can access bar_t and user_foo_t inherits.
Is it same as attributes work ?
A permission is often granted implicitly via attributes.
We have to check a type declaration and attached attributes,
when a permission is granted to types/attributes.
When a type is declared with attribute, we have to check this.
When a type is declared with parent type, we have to check this.
Both are essentially same, I think.
> If we want to make a change to the inheritance it doesn't change the access
> granted to just one domain or type but instead it operates on an unknown
> number of domains/types.
Sorry, what does mean 'make a change to the inheritance' ?
If it means that changing the permission attached to parent-type make effects
to some child-types, 'unknown number of domains/types' is over expression.
A permission granted via parent-type is limited to child-types explicitly
declared as an inherited type.
If it means that changing the relationship between parent and child make effects
to some child-types, it is fact that we have to grant all necessary permissions
to child-types from scrach. But I think it's redundant and needlessness.
This situation is similar trying to declare a new file-type without file_type attributes.
>>Does the example of user_t/user_r/user_ssh_t mean 'inherited domain'?
>>It has not been a significant issue yet, I think.
>>I think it's enough benefit to create a new type which can be accessed from
>>multi domains. (e.g Apache & FTPd shared directory)
>
>
> It does mean inherited domain.
>
> I want to write policy such that someone can load a binary policy module for a
> new user role professor_r which then automatically creates the domain
> professor_foo_t because the base policy has appropriate statements that are
> equivalent in functionality to the macros we currently use in macros/programs
> for such things.
Generally, any methods have strong and weak point.
I have no intention to disallow the availability of existing macros.
Each methods should be used for own strong point.
Thanks,
--
Linux Promotion Center, NEC
KaiGai Kohei <kaigai@ak.jp.nec.com>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-03-23 13:56 ` Stephen Smalley
@ 2005-04-16 7:31 ` KaiGai Kohei
2005-04-18 12:25 ` Stephen Smalley
0 siblings, 1 reply; 58+ messages in thread
From: KaiGai Kohei @ 2005-04-16 7:31 UTC (permalink / raw)
To: Stephen Smalley; +Cc: Kaigai Kohei, SELinux Mail List
[-- Attachment #1: Type: text/plain, Size: 1150 bytes --]
Hello,
>>I tried to modify the Fedora-C3's strict policy for quick testing,
>>and represent a unified file type of HTTPd/Samba/FTPd.
>>
>>I intend to access /var/www/ftp via HTTP and FTP, /var/www/samba via HTTP and Samba.
>>The following configuration was necessary for this purpose.
>>
>>BTW, since any macros (such as apache) were so complex for me, the following
>>configuration may be insufficiency in a precise sense.
>>But it's easily understandable as a configuration sample for real application,
>>I think.
>
>
> Thanks for the additional patch and the example. I'd like to encourage
> people on the list who are actively writing policies to look at this
> language extension and example and comment on whether they think it
> would be helpful to them.
How is the current status of inheritable-type patch ?
Can I think that we can use such statements checkpolicy-1.24 or later ?
Please, don't forget. :-)
I modified the latest patch against to checkpolicy-1.23.1 on Fedora's CVS.
Since there is only one FAILED hunk on checkpolicy.c:518, I modified this.
Thanks,
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
[-- Attachment #2: checkpolicy-1.23.1-extends.patch --]
[-- Type: text/plain, Size: 24879 bytes --]
--- checkpolicy-1.23.1/checkpolicy.h 2005-04-14 16:27:34.000000000 -0400
+++ checkpolicy-1.23.1-extends/checkpolicy.h 2005-04-16 16:37:42.000000000 -0400
@@ -7,6 +7,7 @@ typedef struct te_assert {
ebitmap_t stypes;
ebitmap_t ttypes;
ebitmap_t tclasses;
+ ebitmap_t inherit;
int self;
access_vector_t *avp;
unsigned long line;
@@ -18,4 +19,16 @@ te_assert_t *te_assertions;
extern unsigned int policyvers;
extern unsigned int mlspol;
+/* type was not indexed in policydb,
+ but it's necessary for extends support. */
+extern type_datum_t **type_val_to_struct;
+extern int num_type_val_to_struct;
+extern void get_child_types(ebitmap_t *set, type_datum_t *t, int recursive);
+
+static inline type_datum_t *get_type(int typeval) {
+ if (!type_val_to_struct || typeval<1 || typeval>num_type_val_to_struct)
+ return NULL;
+ return type_val_to_struct[typeval-1];
+}
+
#endif
--- checkpolicy-1.23.1/checkpolicy.c 2005-04-14 16:27:34.000000000 -0400
+++ checkpolicy-1.23.1-extends/checkpolicy.c 2005-04-16 16:39:32.000000000 -0400
@@ -345,8 +345,10 @@ void check_assertion_helper(unsigned int
void check_assertions(void)
{
+ ebitmap_t temp;
+ type_datum_t *typedatum;
te_assert_t *a, *tmp;
- unsigned int i, j;
+ unsigned int i, j, k;
a = te_assertions;
while (a) {
@@ -354,7 +356,23 @@ void check_assertions(void)
if (!ebitmap_get_bit(&a->stypes, i))
continue;
if (a->self) {
- check_assertion_helper(i, i, &a->tclasses, a->avp, a->line);
+ typedatum = type_val_to_struct[i];
+ if (!typedatum) {
+ fprintf(stderr, "BUG: check_assetion for undefined type.\n");
+ exit(1);
+ }
+ ebitmap_init(&temp);
+ get_child_types(&temp, typedatum, ebitmap_get_bit(&a->inherit, i));
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if (!ebitmap_get_bit(&temp, j))
+ continue;
+ for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+ if (!ebitmap_get_bit(&temp, k))
+ continue;
+ check_assertion_helper(j, k, &a->tclasses, a->avp, a->line);
+ }
+ }
+ ebitmap_destroy(&temp);
}
for (j = ebitmap_startbit(&a->ttypes); j < ebitmap_length(&a->ttypes); j++) {
if (!ebitmap_get_bit(&a->ttypes, j))
@@ -367,6 +385,7 @@ void check_assertions(void)
ebitmap_destroy(&tmp->stypes);
ebitmap_destroy(&tmp->ttypes);
ebitmap_destroy(&tmp->tclasses);
+ ebitmap_destroy(&tmp->inherit);
free(tmp->avp);
free(tmp);
}
@@ -443,6 +462,49 @@ int change_bool(char *name, int state)
return 0;
}
+type_datum_t **type_val_to_struct = NULL;
+int num_type_val_to_struct = -1;
+
+static int type_val_to_struct_helper(hashtab_key_t k, hashtab_datum_t d, void *args)
+{
+ type_datum_t *t = (type_datum_t *)d;
+ if (!t->isattr && t->primary)
+ type_val_to_struct[t->value-1] = t;
+ return 0; /* always success */
+}
+
+void get_child_types(ebitmap_t *set, type_datum_t *td, int recur)
+{
+ type_datum_t *child;
+ int i;
+
+ if (!td->isattr && !td->primary)
+ td = get_type(td->value);
+
+ if (!td->isattr) {
+ ebitmap_set_bit(set, td->value - 1, 1);
+ if (!recur)
+ return;
+ for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+ if (!ebitmap_get_bit(&td->types, i))
+ continue;
+ child = type_val_to_struct[i];
+ get_child_types(set, child, recur);
+ }
+ } else {
+ for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+ if (!ebitmap_get_bit(&td->types, i))
+ continue;
+ if (!recur) {
+ ebitmap_set_bit(set, i, 1);
+ } else {
+ child = type_val_to_struct[i];
+ get_child_types(set, child, recur);
+ }
+ }
+ }
+}
+
int main(int argc, char **argv)
{
security_class_t tclass;
@@ -457,7 +519,7 @@ int main(int argc, char **argv)
unsigned int binary = 0, debug = 0;
struct val_to_name v;
int ret, ch, fd;
- unsigned int nel, uret;
+ unsigned int nel, len, uret;
struct stat sb;
void *map;
FILE *outfp = NULL;
@@ -594,6 +656,18 @@ int main(int argc, char **argv)
fprintf(stderr, "%s: error(s) encountered while parsing configuration\n", argv[0]);
exit(1);
}
+
+ /* construction of type_val_to_struct */
+ num_type_val_to_struct = policydbp->p_types.nprim;
+ len = sizeof(type_datum_t *) * num_type_val_to_struct;
+ type_val_to_struct = (type_datum_t **)malloc(len);
+ if (!type_val_to_struct) {
+ fprintf(stderr, "type_val_to_struct: out of memory\n");
+ exit(1);
+ }
+ memset(type_val_to_struct, 0, len);
+ hashtab_map(policydbp->p_types.table, type_val_to_struct_helper, NULL);
+
rewind(yyin);
policydb_lineno = 1;
source_file[0] = '\0';
--- checkpolicy-1.23.1/policy_scan.l 2005-04-14 16:27:34.000000000 -0400
+++ checkpolicy-1.23.1-extends/policy_scan.l 2005-04-16 16:37:42.000000000 -0400
@@ -69,6 +69,8 @@ TYPEALIAS |
typealias { return(TYPEALIAS); }
TYPEATTRIBUTE |
typeattribute { return(TYPEATTRIBUTE); }
+TYPEEXTENDS |
+typeextends { return(TYPEEXTENDS); }
TYPE |
type { return(TYPE); }
BOOL |
@@ -79,6 +81,8 @@ ELSE |
else { return(ELSE); }
ALIAS |
alias { return(ALIAS); }
+EXTENDS |
+extends { return(EXTENDS); }
ATTRIBUTE |
attribute { return(ATTRIBUTE); }
TYPE_TRANSITION |
@@ -216,7 +220,8 @@ H2 { return(H2); }
"." |
"]" |
"~" |
-"*" { return(yytext[0]); }
+"*" |
+"@" { return(yytext[0]); }
. { yywarn("unrecognized character");}
%%
int yyerror(char *msg)
--- checkpolicy-1.23.1/policy_parse.y 2005-04-14 16:27:34.000000000 -0400
+++ checkpolicy-1.23.1-extends/policy_parse.y 2005-04-16 16:37:42.000000000 -0400
@@ -19,6 +19,11 @@
* the Free Software Foundation, version 2.
*/
+/* Updated: KaiGai Kohei, <kaigai@ak.jp.nec.com>
+ * Added inherited type extensions and '@' prefix. (2005/03/21)
+ */
+
+
/* FLASK */
%{
@@ -76,8 +81,8 @@ static int define_category(void);
static int define_level(void);
static int define_attrib(void);
static int define_typealias(void);
-static int define_typeattribute(void);
-static int define_type(int alias);
+static int define_typeattribute(int extends);
+static int define_type(int alias, int extends);
static int define_compute_type(int which);
static int define_te_avtab(int which);
static int define_role_types(void);
@@ -134,9 +139,11 @@ static int define_ipv6_node_context(void
%token ROLES
%token TYPEALIAS
%token TYPEATTRIBUTE
+%token TYPEEXTENDS
%token TYPE
%token TYPES
%token ALIAS
+%token EXTENDS
%token ATTRIBUTE
%token BOOL
%token IF
@@ -289,6 +296,7 @@ te_decl : attribute_def
| type_def
| typealias_def
| typeattribute_def
+ | typeextends_def
| bool_def
| transition_def
| range_trans_def
@@ -299,19 +307,28 @@ attribute_def : ATTRIBUTE iden
{ if (define_attrib()) return -1;}
;
type_def : TYPE identifier alias_def opt_attr_list ';'
- {if (define_type(1)) return -1;}
+ {if (define_type(1, 0)) return -1;}
| TYPE identifier opt_attr_list ';'
- {if (define_type(0)) return -1;}
+ {if (define_type(0, 0)) return -1;}
+ | TYPE identifier alias_def opt_extends_list ';'
+ {if (define_type(1, 1)) return -1;}
+ | TYPE identifier opt_extends_list ';'
+ {if (define_type(0, 1)) return -1;}
;
typealias_def : TYPEALIAS identifier alias_def ';'
{if (define_typealias()) return -1;}
;
typeattribute_def : TYPEATTRIBUTE identifier id_comma_list ';'
- {if (define_typeattribute()) return -1;}
+ {if (define_typeattribute(0)) return -1;}
+ ;
+typeextends_def : TYPEEXTENDS identifier EXTENDS id_comma_list ';'
+ {if (define_typeattribute(1)) return -1;}
;
opt_attr_list : ',' id_comma_list
|
;
+opt_extends_list : EXTENDS id_comma_list
+ ;
bool_def : BOOL identifier bool_val ';'
{if (define_bool()) return -1;}
;
@@ -513,13 +530,13 @@ cexpr_prim : U1 op U2
| R3 op { if (insert_separator(1)) return -1; } names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_ROLE | CEXPR_XTARGET), $2);
if ($$ == 0) return -1; }
- | T1 op { if (insert_separator(1)) return -1; } names_push
+ | T1 op { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, $2);
if ($$ == 0) return -1; }
- | T2 op { if (insert_separator(1)) return -1; } names_push
+ | T2 op { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), $2);
if ($$ == 0) return -1; }
- | T3 op { if (insert_separator(1)) return -1; } names_push
+ | T3 op { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_XTARGET), $2);
if ($$ == 0) return -1; }
| SAMEUSER
@@ -534,10 +551,10 @@ cexpr_prim : U1 op U2
| ROLE role_mls_op
{ $$ = define_cexpr(CEXPR_ATTR, CEXPR_ROLE, $2);
if ($$ == 0) return -1; }
- | SOURCE TYPE { if (insert_separator(1)) return -1; } names_push
+ | SOURCE TYPE { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, CEXPR_TYPE, CEXPR_EQ);
if ($$ == 0) return -1; }
- | TARGET TYPE { if (insert_separator(1)) return -1; } names_push
+ | TARGET TYPE { if (insert_separator(1)) return -1; } type_names_push
{ $$ = define_cexpr(CEXPR_NAMES, (CEXPR_TYPE | CEXPR_TARGET), CEXPR_EQ);
if ($$ == 0) return -1; }
| L1 role_mls_op L2
@@ -690,20 +707,27 @@ tilde : '~'
;
asterisk : '*'
;
-names : identifier
+atmark : '@'
+ ;
+type_identifier : IDENTIFIER
+ { if (insert_id(yytext, 0)) return -1; }
+ | atmark IDENTIFIER
+ { if (insert_id("@", 0) || insert_id(yytext, 0)) return -1; }
+ ;
+names : type_identifier
{ if (insert_separator(0)) return -1; }
| nested_id_set
{ if (insert_separator(0)) return -1; }
| asterisk
{ if (insert_id("*", 0)) return -1;
if (insert_separator(0)) return -1; }
- | tilde identifier
+ | tilde type_identifier
{ if (insert_id("~", 0)) return -1;
if (insert_separator(0)) return -1; }
| tilde nested_id_set
- { if (insert_id("~", 0)) return -1;
+ { if (insert_id("~", 0)) return -1;
if (insert_separator(0)) return -1; }
- | identifier '-' { if (insert_id("-", 0)) return -1; } identifier
+ | type_identifier '-' { if (insert_id("-", 0)) return -1; } type_identifier
{ if (insert_separator(0)) return -1; }
;
tilde_push : tilde
@@ -712,6 +736,19 @@ tilde_push : tilde
asterisk_push : asterisk
{ if (insert_id("*", 1)) return -1; }
;
+type_names_push : type_identifier_push
+ | '{' type_identifier_list_push '}'
+ | tilde_push type_identifier_push
+ | tilde_push '{' type_identifier_list_push '}'
+ ;
+type_identifier_list_push : type_identifier_push
+ | type_identifier_list_push type_identifier_push
+ ;
+type_identifier_push : IDENTIFIER
+ { if (insert_id(yytext,1)) return -1; }
+ | atmark IDENTIFIER
+ { if (insert_id(yytext,1)||insert_id("@",1)) return -1;}
+ ;
names_push : identifier_push
| '{' identifier_list_push '}'
| asterisk_push
@@ -731,7 +768,9 @@ nested_id_set : '{' nested_id_
;
nested_id_list : nested_id_element | nested_id_list nested_id_element
;
-nested_id_element : identifier | '-' { if (insert_id("-", 0)) return -1; } identifier | nested_id_set
+nested_id_element : type_identifier
+ | '-' { if (insert_id("-", 0)) return -1; } type_identifier
+ | nested_id_set
;
identifier : IDENTIFIER
{ if (insert_id(yytext,0)) return -1; }
@@ -1564,10 +1603,35 @@ static int define_typealias(void)
return 0;
}
-static int define_typeattribute(void)
+static int check_loop_inheritance(type_datum_t *td, int parent_typeval)
+{
+ type_datum_t *child;
+ int i;
+
+ /* attribute never have inheritance loop */
+ if (td->isattr)
+ return 0;
+
+ for (i = ebitmap_startbit(&td->types); i < ebitmap_length(&td->types); i++) {
+ if (!ebitmap_get_bit(&td->types, i))
+ continue;
+ if ( parent_typeval - 1 == i )
+ return -1; /* Loop inheritance detected */
+ child = get_type(i+1);
+ if (!child) {
+ yyerror("BUG: unregistered type");
+ return -1;
+ }
+ if (check_loop_inheritance(child, parent_typeval))
+ return -1;
+ }
+ return 0;
+}
+
+static int define_typeattribute(int extends)
{
char *id;
- type_datum_t *t, *attr;
+ type_datum_t *t, *inherit;
if (pass == 2) {
while ((id = queue_remove(id_queue)))
@@ -1590,16 +1654,17 @@ static int define_typeattribute(void)
}
while ((id = queue_remove(id_queue))) {
- attr = hashtab_search(policydbp->p_types.table, id);
- if (!attr) {
- sprintf(errormsg, "attribute %s is not declared", id);
+ inherit = hashtab_search(policydbp->p_types.table, id);
+ if (!inherit) {
+ sprintf(errormsg, "%sattribute %s is not declared",
+ (extends ? "type/" : ""), id);
/* treat it as a fatal error */
yyerror(errormsg);
free(id);
return -1;
}
- if (!attr->isattr) {
+ if (!extends && !inherit->isattr) {
sprintf(errormsg, "%s is a type, not an attribute", id);
yyerror(errormsg);
free(id);
@@ -1608,7 +1673,12 @@ static int define_typeattribute(void)
free(id);
- if (ebitmap_set_bit(&attr->types, (t->value - 1), TRUE)) {
+ if (check_loop_inheritance(t, inherit->value)) {
+ yyerror("inheritance loop is detected");
+ return -1;
+ }
+
+ if (ebitmap_set_bit(&inherit->types, (t->value - 1), TRUE)) {
yyerror("out of memory");
return -1;
}
@@ -1617,10 +1687,10 @@ static int define_typeattribute(void)
return 0;
}
-static int define_type(int alias)
+static int define_type(int alias, int extends)
{
char *id;
- type_datum_t *datum, *aliasdatum, *attr;
+ type_datum_t *datum, *aliasdatum, *inherit;
int ret, newattr = 0;
@@ -1698,9 +1768,10 @@ static int define_type(int alias)
}
while ((id = queue_remove(id_queue))) {
- attr = hashtab_search(policydbp->p_types.table, id);
- if (!attr) {
- sprintf(errormsg, "attribute %s is not declared", id);
+ inherit = hashtab_search(policydbp->p_types.table, id);
+ if (!inherit) {
+ sprintf(errormsg, "%sattribute %s is not declared",
+ (extends)?"type/":"", id);
#if 1
/* treat it as a fatal error */
yyerror(errormsg);
@@ -1729,7 +1800,7 @@ static int define_type(int alias)
newattr = 0;
}
- if (!attr->isattr) {
+ if (!extends && !inherit->isattr) {
sprintf(errormsg, "%s is a type, not an attribute", id);
yyerror(errormsg);
return -1;
@@ -1738,7 +1809,7 @@ static int define_type(int alias)
if (!newattr)
free(id);
- ebitmap_set_bit(&attr->types, datum->value - 1, TRUE);
+ ebitmap_set_bit(&inherit->types, datum->value - 1, TRUE);
}
return 0;
@@ -1780,11 +1851,13 @@ static char *type_val_to_name(unsigned i
static int set_types(ebitmap_t *set,
ebitmap_t *negset,
+ ebitmap_t *inherit,
char *id,
int *add)
{
type_datum_t *t;
unsigned int i;
+ ebitmap_t temp;
if (strcmp(id, "*") == 0) {
/* set all types not in negset */
@@ -1809,10 +1882,16 @@ static int set_types(ebitmap_t *set,
}
if (strcmp(id, "-") == 0) {
- *add = 0;
+ *add &= 0xfffe; /* clear bit 0*/
+ free(id);
+ return 0;
+ }
+
+ if (strcmp(id, "@") == 0) {
+ *add |= 0x0002; /* set bit 1 */
free(id);
return 0;
- }
+ }
t = hashtab_search(policydbp->p_types.table, id);
if (!t) {
@@ -1821,42 +1900,28 @@ static int set_types(ebitmap_t *set,
free(id);
return -1;
}
+ if (inherit && ((*add)&0x0002)!=0 )
+ ebitmap_set_bit(inherit, t->value - 1, TRUE);
- if (t->isattr) {
- /* set or clear all types with this attribute,
- but do not set anything explicitly cleared previously */
- for (i = ebitmap_startbit(&t->types); i < ebitmap_length(&t->types); i++) {
- if (!ebitmap_get_bit(&t->types, i))
- continue;
- if (!(*add)) {
- ebitmap_set_bit(set, i, FALSE);
- ebitmap_set_bit(negset, i, TRUE);
- } else if (!ebitmap_get_bit(negset, i)) {
- ebitmap_set_bit(set, i, TRUE);
-#if VERBOSE
- } else {
- char *name = type_val_to_name(i+1);
- sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
- yywarn(errormsg);
-#endif
- }
- }
- } else {
- /* set or clear one type, but do not set anything
- explicitly cleared previously */
- if (!(*add)) {
- ebitmap_set_bit(set, t->value - 1, FALSE);
- ebitmap_set_bit(negset, t->value - 1, TRUE);
- } else if (!ebitmap_get_bit(negset, t->value - 1)) {
- ebitmap_set_bit(set, t->value - 1, TRUE);
+ ebitmap_init(&temp);
+ get_child_types(&temp, t, (*add)&0x0002);
+ for (i = ebitmap_startbit(&temp); i < ebitmap_length(&temp); i++) {
+ if (!ebitmap_get_bit(&temp, i))
+ continue;
+ if (!((*add)&0x0001)) {
+ ebitmap_set_bit(set, i, FALSE);
+ ebitmap_set_bit(negset, i, TRUE);
+ } else if (!ebitmap_get_bit(negset, i)) {
+ ebitmap_set_bit(set, i, TRUE);
#if VERBOSE
} else {
- sprintf(errormsg, "ignoring %s due to prior -%s", id, id);
+ char *name = type_val_to_name(i+1);
+ sprintf(errormsg, "ignoring %s due to prior -%s", name, name);
yywarn(errormsg);
#endif
}
}
-
+ ebitmap_destroy(&temp);
free(id);
*add = 1;
return 0;
@@ -1893,14 +1958,14 @@ static int define_compute_type(int which
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -2033,14 +2098,14 @@ static cond_av_list_t *define_cond_compu
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, NULL, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
@@ -2445,9 +2510,10 @@ static cond_av_list_t *define_cond_te_av
cond_av_list_t *sub_list, *final_list, *tail;
class_datum_t *cladatum;
perm_datum_t *perdatum;
- ebitmap_t stypes, ttypes, tclasses, negset;
+ type_datum_t *typedatum;
+ ebitmap_t stypes, ttypes, tclasses, temp, inherit, negset;
access_vector_t *avp;
- int i, j, hiclass, self = 0, add = 1;
+ int i, j, k, hiclass, self = 0, add = 1;
int suppress = 0;
if (pass == 1) {
@@ -2465,10 +2531,11 @@ static cond_av_list_t *define_cond_te_av
ebitmap_init(&stypes);
ebitmap_init(&ttypes);
ebitmap_init(&tclasses);
+ ebitmap_init(&inherit);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, &inherit, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
@@ -2479,7 +2546,7 @@ static cond_av_list_t *define_cond_te_av
self = 1;
continue;
}
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return COND_ERR;
}
ebitmap_destroy(&negset);
@@ -2568,19 +2635,36 @@ static cond_av_list_t *define_cond_te_av
for (i = ebitmap_startbit(&stypes); i < ebitmap_length(&stypes); i++) {
if (!ebitmap_get_bit(&stypes, i))
continue;
- if (self) {
- if ((sub_list = cond_te_avtab_helper(which, i, i, &tclasses, avp )) == COND_ERR)
- return COND_ERR;
- if (final_list) {
- tail->next = sub_list;
- while (tail->next != NULL)
- tail = tail->next;
- } else {
- final_list = sub_list;
- tail = final_list;
- while (tail->next != NULL)
- tail = tail->next;
+ typedatum = get_type(i+1);
+ if (!typedatum)
+ return COND_ERR;
+ ebitmap_init(&temp);
+ /* If the source type is given with '@' prefix,
+ 'self' also includes own child types. */
+ get_child_types(&temp, typedatum, ebitmap_get_bit(&inherit,i));
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if(!ebitmap_get_bit(&temp, j))
+ continue;
+ for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+ if(!ebitmap_get_bit(&temp, k))
+ continue;
+ sub_list = cond_te_avtab_helper(which, j, k, &tclasses, avp);
+ if (sub_list==COND_ERR) {
+ ebitmap_destroy(&temp);
+ return COND_ERR;
+ }
+ if (final_list) {
+ tail->next = sub_list;
+ while (tail->next != NULL)
+ tail = tail->next;
+ } else {
+ final_list = sub_list;
+ tail = final_list;
+ while (tail->next != NULL)
+ tail = tail->next;
+ }
}
+ ebitmap_destroy(&temp);
}
}
}
@@ -2621,9 +2705,10 @@ static int define_te_avtab(int which)
char *id;
class_datum_t *cladatum;
perm_datum_t *perdatum;
- ebitmap_t stypes, ttypes, tclasses, negset;
+ type_datum_t *typedatum;
+ ebitmap_t stypes, ttypes, tclasses, temp, inherit, negset;
access_vector_t *avp;
- unsigned int i, j, hiclass;
+ unsigned int i, j, k, hiclass;
int self = 0, add = 1;
te_assert_t *newassert;
int suppress = 0;
@@ -2643,10 +2728,11 @@ static int define_te_avtab(int which)
ebitmap_init(&stypes);
ebitmap_init(&ttypes);
ebitmap_init(&tclasses);
+ ebitmap_init(&inherit);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&stypes, &negset, id, &add))
+ if (set_types(&stypes, &negset, &inherit, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -2657,7 +2743,7 @@ static int define_te_avtab(int which)
self = 1;
continue;
}
- if (set_types(&ttypes, &negset, id, &add))
+ if (set_types(&ttypes, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -2749,6 +2835,7 @@ static int define_te_avtab(int which)
newassert->stypes = stypes;
newassert->ttypes = ttypes;
newassert->tclasses = tclasses;
+ newassert->inherit = inherit;
newassert->self = self;
newassert->avp = avp;
newassert->line = policydb_lineno;
@@ -2761,8 +2848,26 @@ static int define_te_avtab(int which)
if (!ebitmap_get_bit(&stypes, i))
continue;
if (self) {
- if (te_avtab_helper(which, i, i, &tclasses, avp))
+ typedatum = get_type(i+1);
+ if (!typedatum)
return -1;
+ ebitmap_init(&temp);
+ /* If the source type is given with '@' prefix,
+ 'self' means own child types. */
+ get_child_types(&temp, typedatum, ebitmap_get_bit(&inherit, i));
+ for (j = ebitmap_startbit(&temp); j < ebitmap_length(&temp); j++) {
+ if (!ebitmap_get_bit(&temp, j))
+ continue;
+ for (k = ebitmap_startbit(&temp); k < ebitmap_length(&temp); k++) {
+ if (!ebitmap_get_bit(&temp, k))
+ continue;
+ if (te_avtab_helper(which, j, k, &tclasses, avp)) {
+ ebitmap_destroy(&temp);
+ return -1;
+ }
+ }
+ }
+ ebitmap_destroy(&temp);
}
for (j = ebitmap_startbit(&ttypes); j < ebitmap_length(&ttypes); j++) {
if (!ebitmap_get_bit(&ttypes, j))
@@ -2853,7 +2958,7 @@ static int define_role_types(void)
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&role->types, &negset, id, &add))
+ if (set_types(&role->types, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -3068,7 +3173,7 @@ static int define_role_trans(void)
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&types, &negset, id, &add))
+ if (set_types(&types, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
@@ -3493,7 +3598,7 @@ static uintptr_t
}
val = role->value;
} else if (expr->attr & CEXPR_TYPE) {
- if (set_types(&expr->names, &negset, id, &add)) {
+ if (set_types(&expr->names, &negset, NULL, id, &add)) {
free(expr);
return 0;
}
@@ -4839,14 +4944,14 @@ static int define_range_trans(void)
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&doms, &negset, id, &add))
+ if (set_types(&doms, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
ebitmap_init(&negset);
while ((id = queue_remove(id_queue))) {
- if (set_types(&types, &negset, id, &add))
+ if (set_types(&types, &negset, NULL, id, &add))
return -1;
}
ebitmap_destroy(&negset);
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-04-16 7:31 ` KaiGai Kohei
@ 2005-04-18 12:25 ` Stephen Smalley
2005-04-18 16:57 ` KaiGai Kohei
0 siblings, 1 reply; 58+ messages in thread
From: Stephen Smalley @ 2005-04-18 12:25 UTC (permalink / raw)
To: KaiGai Kohei; +Cc: Kaigai Kohei, SELinux Mail List
On Sat, 2005-04-16 at 16:31 +0900, KaiGai Kohei wrote:
> How is the current status of inheritable-type patch ?
> Can I think that we can use such statements checkpolicy-1.24 or later ?
> Please, don't forget. :-)
>
> I modified the latest patch against to checkpolicy-1.23.1 on Fedora's CVS.
> Since there is only one FAILED hunk on checkpolicy.c:518, I modified this.
Hi,
Thanks for updating the patch. However, from the discussions on the
list, I haven't seen any clear indication that this new language
feature:
a) solves a real problem in a superior manner to the use of macros, and
b) is being demanded by people who are presently developing policy.
I'm willing to be convinced otherwise, but I just haven't seen the
evidence for it yet. Have you considered working on a template feature
for the language instead, as that clearly would be beneficial?
--
Stephen Smalley <sds@tycho.nsa.gov>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
* Re: [RFC & PATCH] inherited type definition.
2005-04-18 12:25 ` Stephen Smalley
@ 2005-04-18 16:57 ` KaiGai Kohei
0 siblings, 0 replies; 58+ messages in thread
From: KaiGai Kohei @ 2005-04-18 16:57 UTC (permalink / raw)
To: Stephen Smalley; +Cc: Kaigai Kohei, SELinux Mail List
Hello, Thanks for your comments.
> Thanks for updating the patch. However, from the discussions on the
> list, I haven't seen any clear indication that this new language
> feature:
> a) solves a real problem in a superior manner to the use of macros, and
One example is Samba, FTP and Apache combined type definition.
If we try to solve this requirement with existing macros only,
we have to describe the access-permit macros for each type
as I said in past days.
In addition, I intend to use domain inheritance for my original policy
configuration only, because it's strongly opposed to merge into upstream.
But it's useful for developing the application with setcon(), I think.
When we intend to execute a child process in separate domain from the parent,
there are some common permission such as shared-memory, and so on.
It's redandant to grant same permissions for each domain, even if it's
done by any macros. If parent-type is granted the common permission,
we can restrain redandancy and human-errors by duplication of configuration.
Sorry, above example is not real-world application like apache.
But I think the definition of relationship between types is
useful functionality for developing SELinux aware applications.
> b) is being demanded by people who are presently developing policy.
Since the existing policy has been written by macros yet, the quiet
requirement for type-inheritance is indeed natural.
But I think type-inheritance is useful for appropriate field
on developing new policy.
Of course, we can select using macros depending on circumstances.
> I'm willing to be convinced otherwise, but I just haven't seen the
> evidence for it yet. Have you considered working on a template feature
> for the language instead, as that clearly would be beneficial?
In my understanding, template feature defines horizontal relationship of types.
e.g) the relationship of staff_t, staff_home_dir_t and staff_home_t.
Type inheritance defines vertical relationship of types.
e.g) the relationship of samba_share_t, ftp_anon_t and those combined type.
Those features provide another worth. Am I wrong ?
Thanks,
--
DO NOTHING IS THE WORST POLICY.
KaiGai Kohei <kaigai@kaigai.gr.jp>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 58+ messages in thread
end of thread, other threads:[~2005-04-18 16:57 UTC | newest]
Thread overview: 58+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-13 16:36 [RFC & PATCH] inherited type definition KaiGai Kohei
2005-03-14 13:17 ` KaiGai Kohei
2005-03-14 13:50 ` Stephen Smalley
2005-03-14 15:13 ` Luke Kenneth Casson Leighton
2005-03-14 15:22 ` Stephen Smalley
2005-03-14 16:01 ` Luke Kenneth Casson Leighton
2005-03-14 19:27 ` Valdis.Kletnieks
2005-03-14 20:10 ` Stephen Smalley
2005-03-14 17:26 ` KaiGai Kohei
2005-03-14 18:10 ` Luke Kenneth Casson Leighton
2005-03-14 18:25 ` Stephen Smalley
2005-03-15 11:50 ` KaiGai Kohei
2005-03-15 14:42 ` Stephen Smalley
2005-03-16 4:42 ` Kaigai Kohei
2005-03-16 10:00 ` Luke Kenneth Casson Leighton
2005-03-16 14:05 ` Stephen Smalley
2005-03-17 9:32 ` Kaigai Kohei
2005-03-17 13:55 ` Stephen Smalley
2005-03-17 14:57 ` KaiGai Kohei
2005-03-21 10:07 ` KaiGai Kohei
2005-03-21 15:59 ` Stephen Smalley
2005-03-23 8:17 ` Kaigai Kohei
2005-03-23 13:56 ` Stephen Smalley
2005-04-16 7:31 ` KaiGai Kohei
2005-04-18 12:25 ` Stephen Smalley
2005-04-18 16:57 ` KaiGai Kohei
2005-03-24 11:06 ` Luke Kenneth Casson Leighton
2005-03-24 12:34 ` Kaigai Kohei
2005-04-06 12:49 ` Russell Coker
2005-04-06 14:50 ` KaiGai Kohei
2005-04-06 15:30 ` Russell Coker
2005-04-06 18:23 ` Jim McCullough
2005-04-07 2:16 ` Kaigai Kohei
2005-04-06 17:55 ` Luke Kenneth Casson Leighton
2005-03-14 16:38 ` Karl MacMillan
2005-03-15 11:47 ` KaiGai Kohei
2005-03-15 14:00 ` Karl MacMillan
2005-03-16 4:35 ` Kaigai Kohei
2005-03-16 10:13 ` Luke Kenneth Casson Leighton
2005-03-16 21:46 ` Karl MacMillan
2005-03-16 21:31 ` Karl MacMillan
2005-03-17 13:05 ` Kaigai Kohei
2005-03-17 19:15 ` Karl MacMillan
2005-03-17 20:07 ` Stephen Smalley
2005-03-17 21:41 ` Karl MacMillan
2005-03-18 13:13 ` Stephen Smalley
2005-03-18 13:56 ` Stephen Smalley
2005-03-18 22:28 ` Karl MacMillan
2005-03-18 23:03 ` Luke Kenneth Casson Leighton
2005-03-20 23:20 ` Karl MacMillan
2005-03-21 0:17 ` Luke Kenneth Casson Leighton
2005-03-21 13:39 ` Karl MacMillan
2005-03-22 0:14 ` Luke Kenneth Casson Leighton
2005-03-22 13:53 ` Karl MacMillan
2005-03-24 11:04 ` Luke Kenneth Casson Leighton
2005-03-24 12:31 ` Kaigai Kohei
2005-03-24 22:19 ` Luke Kenneth Casson Leighton
2005-03-24 22:27 ` Luke Kenneth Casson Leighton
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.