aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrel Goeddel <dgoeddel@TrustedCS.com>2006-09-26 02:31:59 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 11:48:52 -0400
commitf3f8771420737004da55159c2f2dc0b6f483a4ef (patch)
tree01ff2aa4dc82cdc5b2383648f9fabb8378250d00
parent016b9bdb81d9c9c7800e4e224ade38d8b37669d3 (diff)
[PATCH] selinux: add support for range transitions on object classes
Introduces support for policy version 21. This version of the binary kernel policy allows for defining range transitions on security classes other than the process security class. As always, backwards compatibility for older formats is retained. The security class is read in as specified when using the new format, while the "process" security class is assumed when using an older policy format. Signed-off-by: Darrel Goeddel <dgoeddel@trustedcs.com> Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Acked-by: James Morris <jmorris@namei.org> Acked-by: Eric Paris <eparis@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--security/selinux/Kconfig2
-rw-r--r--security/selinux/include/security.h3
-rw-r--r--security/selinux/ss/mls.c21
-rw-r--r--security/selinux/ss/policydb.c27
-rw-r--r--security/selinux/ss/policydb.h7
5 files changed, 37 insertions, 23 deletions
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index 5c64c746b062..293dbd6246c1 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -145,7 +145,7 @@ config SECURITY_SELINUX_POLICYDB_VERSION_MAX
145config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE 145config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
146 int "NSA SELinux maximum supported policy format version value" 146 int "NSA SELinux maximum supported policy format version value"
147 depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX 147 depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
148 range 15 20 148 range 15 21
149 default 19 149 default 19
150 help 150 help
151 This option sets the value for the maximum policy format version 151 This option sets the value for the maximum policy format version
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index aa21ca1721af..1ef79172cc8c 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -24,13 +24,14 @@
24#define POLICYDB_VERSION_VALIDATETRANS 19 24#define POLICYDB_VERSION_VALIDATETRANS 19
25#define POLICYDB_VERSION_MLS 19 25#define POLICYDB_VERSION_MLS 19
26#define POLICYDB_VERSION_AVTAB 20 26#define POLICYDB_VERSION_AVTAB 20
27#define POLICYDB_VERSION_RANGETRANS 21
27 28
28/* Range of policy versions we understand*/ 29/* Range of policy versions we understand*/
29#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 30#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
30#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX 31#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
31#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE 32#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
32#else 33#else
33#define POLICYDB_VERSION_MAX POLICYDB_VERSION_AVTAB 34#define POLICYDB_VERSION_MAX POLICYDB_VERSION_RANGETRANS
34#endif 35#endif
35 36
36extern int selinux_enabled; 37extern int selinux_enabled;
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c
index 119bd6078ba1..c713af23250a 100644
--- a/security/selinux/ss/mls.c
+++ b/security/selinux/ss/mls.c
@@ -530,22 +530,21 @@ int mls_compute_sid(struct context *scontext,
530 u32 specified, 530 u32 specified,
531 struct context *newcontext) 531 struct context *newcontext)
532{ 532{
533 struct range_trans *rtr;
534
533 if (!selinux_mls_enabled) 535 if (!selinux_mls_enabled)
534 return 0; 536 return 0;
535 537
536 switch (specified) { 538 switch (specified) {
537 case AVTAB_TRANSITION: 539 case AVTAB_TRANSITION:
538 if (tclass == SECCLASS_PROCESS) { 540 /* Look for a range transition rule. */
539 struct range_trans *rangetr; 541 for (rtr = policydb.range_tr; rtr; rtr = rtr->next) {
540 /* Look for a range transition rule. */ 542 if (rtr->source_type == scontext->type &&
541 for (rangetr = policydb.range_tr; rangetr; 543 rtr->target_type == tcontext->type &&
542 rangetr = rangetr->next) { 544 rtr->target_class == tclass) {
543 if (rangetr->dom == scontext->type && 545 /* Set the range from the rule */
544 rangetr->type == tcontext->type) { 546 return mls_range_set(newcontext,
545 /* Set the range from the rule */ 547 &rtr->target_range);
546 return mls_range_set(newcontext,
547 &rangetr->range);
548 }
549 } 548 }
550 } 549 }
551 /* Fallthrough */ 550 /* Fallthrough */
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index f03960e697ce..b18895302555 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -96,6 +96,11 @@ static struct policydb_compat_info policydb_compat[] = {
96 .sym_num = SYM_NUM, 96 .sym_num = SYM_NUM,
97 .ocon_num = OCON_NUM, 97 .ocon_num = OCON_NUM,
98 }, 98 },
99 {
100 .version = POLICYDB_VERSION_RANGETRANS,
101 .sym_num = SYM_NUM,
102 .ocon_num = OCON_NUM,
103 },
99}; 104};
100 105
101static struct policydb_compat_info *policydb_lookup_compat(int version) 106static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -645,15 +650,15 @@ void policydb_destroy(struct policydb *p)
645 650
646 for (rt = p->range_tr; rt; rt = rt -> next) { 651 for (rt = p->range_tr; rt; rt = rt -> next) {
647 if (lrt) { 652 if (lrt) {
648 ebitmap_destroy(&lrt->range.level[0].cat); 653 ebitmap_destroy(&lrt->target_range.level[0].cat);
649 ebitmap_destroy(&lrt->range.level[1].cat); 654 ebitmap_destroy(&lrt->target_range.level[1].cat);
650 kfree(lrt); 655 kfree(lrt);
651 } 656 }
652 lrt = rt; 657 lrt = rt;
653 } 658 }
654 if (lrt) { 659 if (lrt) {
655 ebitmap_destroy(&lrt->range.level[0].cat); 660 ebitmap_destroy(&lrt->target_range.level[0].cat);
656 ebitmap_destroy(&lrt->range.level[1].cat); 661 ebitmap_destroy(&lrt->target_range.level[1].cat);
657 kfree(lrt); 662 kfree(lrt);
658 } 663 }
659 664
@@ -1829,6 +1834,7 @@ int policydb_read(struct policydb *p, void *fp)
1829 } 1834 }
1830 1835
1831 if (p->policyvers >= POLICYDB_VERSION_MLS) { 1836 if (p->policyvers >= POLICYDB_VERSION_MLS) {
1837 int new_rangetr = p->policyvers >= POLICYDB_VERSION_RANGETRANS;
1832 rc = next_entry(buf, fp, sizeof(u32)); 1838 rc = next_entry(buf, fp, sizeof(u32));
1833 if (rc < 0) 1839 if (rc < 0)
1834 goto bad; 1840 goto bad;
@@ -1847,9 +1853,16 @@ int policydb_read(struct policydb *p, void *fp)
1847 rc = next_entry(buf, fp, (sizeof(u32) * 2)); 1853 rc = next_entry(buf, fp, (sizeof(u32) * 2));
1848 if (rc < 0) 1854 if (rc < 0)
1849 goto bad; 1855 goto bad;
1850 rt->dom = le32_to_cpu(buf[0]); 1856 rt->source_type = le32_to_cpu(buf[0]);
1851 rt->type = le32_to_cpu(buf[1]); 1857 rt->target_type = le32_to_cpu(buf[1]);
1852 rc = mls_read_range_helper(&rt->range, fp); 1858 if (new_rangetr) {
1859 rc = next_entry(buf, fp, sizeof(u32));
1860 if (rc < 0)
1861 goto bad;
1862 rt->target_class = le32_to_cpu(buf[0]);
1863 } else
1864 rt->target_class = SECCLASS_PROCESS;
1865 rc = mls_read_range_helper(&rt->target_range, fp);
1853 if (rc) 1866 if (rc)
1854 goto bad; 1867 goto bad;
1855 lrt = rt; 1868 lrt = rt;
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index b1340711f721..8319d5ff5944 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -106,9 +106,10 @@ struct cat_datum {
106}; 106};
107 107
108struct range_trans { 108struct range_trans {
109 u32 dom; /* current process domain */ 109 u32 source_type;
110 u32 type; /* program executable type */ 110 u32 target_type;
111 struct mls_range range; /* new range */ 111 u32 target_class;
112 struct mls_range target_range;
112 struct range_trans *next; 113 struct range_trans *next;
113}; 114};
114 115