aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/ss/context.h20
-rw-r--r--security/selinux/ss/mls.c24
-rw-r--r--security/selinux/ss/policydb.c25
-rw-r--r--security/selinux/ss/policydb.h13
-rw-r--r--security/selinux/ss/services.c32
6 files changed, 109 insertions, 8 deletions
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index d871e8ad2103..ba53400195c0 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -31,13 +31,14 @@
31#define POLICYDB_VERSION_BOUNDARY 24 31#define POLICYDB_VERSION_BOUNDARY 24
32#define POLICYDB_VERSION_FILENAME_TRANS 25 32#define POLICYDB_VERSION_FILENAME_TRANS 25
33#define POLICYDB_VERSION_ROLETRANS 26 33#define POLICYDB_VERSION_ROLETRANS 26
34#define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 27
34 35
35/* Range of policy versions we understand*/ 36/* Range of policy versions we understand*/
36#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 37#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
37#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX 38#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
38#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE 39#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
39#else 40#else
40#define POLICYDB_VERSION_MAX POLICYDB_VERSION_ROLETRANS 41#define POLICYDB_VERSION_MAX POLICYDB_VERSION_NEW_OBJECT_DEFAULTS
41#endif 42#endif
42 43
43/* Mask for just the mount related flags */ 44/* Mask for just the mount related flags */
diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h
index 45e8fb0515f8..212e3479a0d9 100644
--- a/security/selinux/ss/context.h
+++ b/security/selinux/ss/context.h
@@ -74,6 +74,26 @@ out:
74 return rc; 74 return rc;
75} 75}
76 76
77/*
78 * Sets both levels in the MLS range of 'dst' to the high level of 'src'.
79 */
80static inline int mls_context_cpy_high(struct context *dst, struct context *src)
81{
82 int rc;
83
84 dst->range.level[0].sens = src->range.level[1].sens;
85 rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[1].cat);
86 if (rc)
87 goto out;
88
89 dst->range.level[1].sens = src->range.level[1].sens;
90 rc = ebitmap_cpy(&dst->range.level[1].cat, &src->range.level[1].cat);
91 if (rc)
92 ebitmap_destroy(&dst->range.level[0].cat);
93out:
94 return rc;
95}
96
77static inline int mls_context_cmp(struct context *c1, struct context *c2) 97static inline int mls_context_cmp(struct context *c1, struct context *c2)
78{ 98{
79 return ((c1->range.level[0].sens == c2->range.level[0].sens) && 99 return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index fbf9c5816c71..40de8d3f208e 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -517,6 +517,8 @@ int mls_compute_sid(struct context *scontext,
517{ 517{
518 struct range_trans rtr; 518 struct range_trans rtr;
519 struct mls_range *r; 519 struct mls_range *r;
520 struct class_datum *cladatum;
521 int default_range = 0;
520 522
521 if (!policydb.mls_enabled) 523 if (!policydb.mls_enabled)
522 return 0; 524 return 0;
@@ -530,6 +532,28 @@ int mls_compute_sid(struct context *scontext,
530 r = hashtab_search(policydb.range_tr, &rtr); 532 r = hashtab_search(policydb.range_tr, &rtr);
531 if (r) 533 if (r)
532 return mls_range_set(newcontext, r); 534 return mls_range_set(newcontext, r);
535
536 if (tclass && tclass <= policydb.p_classes.nprim) {
537 cladatum = policydb.class_val_to_struct[tclass - 1];
538 if (cladatum)
539 default_range = cladatum->default_range;
540 }
541
542 switch (default_range) {
543 case DEFAULT_SOURCE_LOW:
544 return mls_context_cpy_low(newcontext, scontext);
545 case DEFAULT_SOURCE_HIGH:
546 return mls_context_cpy_high(newcontext, scontext);
547 case DEFAULT_SOURCE_LOW_HIGH:
548 return mls_context_cpy(newcontext, scontext);
549 case DEFAULT_TARGET_LOW:
550 return mls_context_cpy_low(newcontext, tcontext);
551 case DEFAULT_TARGET_HIGH:
552 return mls_context_cpy_high(newcontext, tcontext);
553 case DEFAULT_TARGET_LOW_HIGH:
554 return mls_context_cpy(newcontext, tcontext);
555 }
556
533 /* Fallthrough */ 557 /* Fallthrough */
534 case AVTAB_CHANGE: 558 case AVTAB_CHANGE:
535 if ((tclass == policydb.process_class) || (sock == true)) 559 if ((tclass == policydb.process_class) || (sock == true))
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index a7f61d52f05c..2bb9c2fd5f1a 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -133,6 +133,11 @@ static struct policydb_compat_info policydb_compat[] = {
133 .sym_num = SYM_NUM, 133 .sym_num = SYM_NUM,
134 .ocon_num = OCON_NUM, 134 .ocon_num = OCON_NUM,
135 }, 135 },
136 {
137 .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
138 .sym_num = SYM_NUM,
139 .ocon_num = OCON_NUM,
140 },
136}; 141};
137 142
138static struct policydb_compat_info *policydb_lookup_compat(int version) 143static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -1306,6 +1311,16 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
1306 goto bad; 1311 goto bad;
1307 } 1312 }
1308 1313
1314 if (p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) {
1315 rc = next_entry(buf, fp, sizeof(u32) * 3);
1316 if (rc)
1317 goto bad;
1318
1319 cladatum->default_user = le32_to_cpu(buf[0]);
1320 cladatum->default_role = le32_to_cpu(buf[1]);
1321 cladatum->default_range = le32_to_cpu(buf[2]);
1322 }
1323
1309 rc = hashtab_insert(h, key, cladatum); 1324 rc = hashtab_insert(h, key, cladatum);
1310 if (rc) 1325 if (rc)
1311 goto bad; 1326 goto bad;
@@ -2832,6 +2847,16 @@ static int class_write(void *vkey, void *datum, void *ptr)
2832 if (rc) 2847 if (rc)
2833 return rc; 2848 return rc;
2834 2849
2850 if (p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) {
2851 buf[0] = cpu_to_le32(cladatum->default_user);
2852 buf[1] = cpu_to_le32(cladatum->default_role);
2853 buf[2] = cpu_to_le32(cladatum->default_range);
2854
2855 rc = put_entry(buf, sizeof(uint32_t), 3, fp);
2856 if (rc)
2857 return rc;
2858 }
2859
2835 return 0; 2860 return 0;
2836} 2861}
2837 2862
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index b846c0387180..a949f1ad43bb 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -60,6 +60,19 @@ struct class_datum {
60 struct symtab permissions; /* class-specific permission symbol table */ 60 struct symtab permissions; /* class-specific permission symbol table */
61 struct constraint_node *constraints; /* constraints on class permissions */ 61 struct constraint_node *constraints; /* constraints on class permissions */
62 struct constraint_node *validatetrans; /* special transition rules */ 62 struct constraint_node *validatetrans; /* special transition rules */
63 /* Options how a new object user and role should be decided */
64#define DEFAULT_SOURCE 1
65#define DEFAULT_TARGET 2
66 char default_user;
67 char default_role;
68/* Options how a new object range should be decided */
69#define DEFAULT_SOURCE_LOW 1
70#define DEFAULT_SOURCE_HIGH 2
71#define DEFAULT_SOURCE_LOW_HIGH 3
72#define DEFAULT_TARGET_LOW 4
73#define DEFAULT_TARGET_HIGH 5
74#define DEFAULT_TARGET_LOW_HIGH 6
75 char default_range;
63}; 76};
64 77
65/* Role attributes */ 78/* Role attributes */
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 185f849a26f6..2ea108c2c048 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1389,6 +1389,7 @@ static int security_compute_sid(u32 ssid,
1389 u32 *out_sid, 1389 u32 *out_sid,
1390 bool kern) 1390 bool kern)
1391{ 1391{
1392 struct class_datum *cladatum = NULL;
1392 struct context *scontext = NULL, *tcontext = NULL, newcontext; 1393 struct context *scontext = NULL, *tcontext = NULL, newcontext;
1393 struct role_trans *roletr = NULL; 1394 struct role_trans *roletr = NULL;
1394 struct avtab_key avkey; 1395 struct avtab_key avkey;
@@ -1437,12 +1438,20 @@ static int security_compute_sid(u32 ssid,
1437 goto out_unlock; 1438 goto out_unlock;
1438 } 1439 }
1439 1440
1441 if (tclass && tclass <= policydb.p_classes.nprim)
1442 cladatum = policydb.class_val_to_struct[tclass - 1];
1443
1440 /* Set the user identity. */ 1444 /* Set the user identity. */
1441 switch (specified) { 1445 switch (specified) {
1442 case AVTAB_TRANSITION: 1446 case AVTAB_TRANSITION:
1443 case AVTAB_CHANGE: 1447 case AVTAB_CHANGE:
1444 /* Use the process user identity. */ 1448 if (cladatum && cladatum->default_user == DEFAULT_TARGET) {
1445 newcontext.user = scontext->user; 1449 newcontext.user = tcontext->user;
1450 } else {
1451 /* notice this gets both DEFAULT_SOURCE and unset */
1452 /* Use the process user identity. */
1453 newcontext.user = scontext->user;
1454 }
1446 break; 1455 break;
1447 case AVTAB_MEMBER: 1456 case AVTAB_MEMBER:
1448 /* Use the related object owner. */ 1457 /* Use the related object owner. */
@@ -1450,14 +1459,23 @@ static int security_compute_sid(u32 ssid,
1450 break; 1459 break;
1451 } 1460 }
1452 1461
1453 /* Set the role and type to default values. */ 1462 /* Set the role to default values. */
1454 if ((tclass == policydb.process_class) || (sock == true)) { 1463 if (cladatum && cladatum->default_role == DEFAULT_SOURCE) {
1455 /* Use the current role and type of process. */
1456 newcontext.role = scontext->role; 1464 newcontext.role = scontext->role;
1465 } else if (cladatum && cladatum->default_role == DEFAULT_TARGET) {
1466 newcontext.role = tcontext->role;
1467 } else {
1468 if ((tclass == policydb.process_class) || (sock == true))
1469 newcontext.role = scontext->role;
1470 else
1471 newcontext.role = OBJECT_R_VAL;
1472 }
1473
1474 /* Set the type to default values. */
1475 if ((tclass == policydb.process_class) || (sock == true)) {
1476 /* Use the type of process. */
1457 newcontext.type = scontext->type; 1477 newcontext.type = scontext->type;
1458 } else { 1478 } else {
1459 /* Use the well-defined object role. */
1460 newcontext.role = OBJECT_R_VAL;
1461 /* Use the type of the related object. */ 1479 /* Use the type of the related object. */
1462 newcontext.type = tcontext->type; 1480 newcontext.type = tcontext->type;
1463 } 1481 }