diff options
author | Stephen Smalley <sds@tycho.nsa.gov> | 2005-09-03 18:55:16 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@evo.osdl.org> | 2005-09-05 03:05:50 -0400 |
commit | 782ebb992ec20b5afdd5786ee8c2f1b58b631f24 (patch) | |
tree | adf0af44fa591d803ec6b9ab7541ff3e5745dd93 /security/selinux/ss/policydb.c | |
parent | 720d6c29e146e96cca858057469951e91e0e6850 (diff) |
[PATCH] selinux: Reduce memory use by avtab
This patch improves memory use by SELinux by both reducing the avtab node
size and reducing the number of avtab nodes. The memory savings are
substantial, e.g. on a 64-bit system after boot, James Morris reported the
following data for the targeted and strict policies:
#objs objsize kernmem
Targeted:
Before: 237888 40 9.1MB
After: 19968 24 468KB
Strict:
Before: 571680 40 21.81MB
After: 221052 24 5.06MB
The improvement in memory use comes at a cost in the speed of security
server computations of access vectors, but these computations are only
required on AVC cache misses, and performance measurements by James Morris
using a number of benchmarks have shown that the change does not cause any
significant degradation.
Note that a rebuilt policy via an updated policy toolchain
(libsepol/checkpolicy) is required in order to gain the full benefits of
this patch, although some memory savings benefits are immediately applied
even to older policies (in particular, the reduction in avtab node size).
Sources for the updated toolchain are presently available from the
sourceforge CVS tree (http://sourceforge.net/cvs/?group_id=21266), and
tarballs are available from http://www.flux.utah.edu/~sds.
Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security/selinux/ss/policydb.c')
-rw-r--r-- | security/selinux/ss/policydb.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index 785c33cf4864..7b03fa0f92b0 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -91,6 +91,11 @@ static struct policydb_compat_info policydb_compat[] = { | |||
91 | .sym_num = SYM_NUM, | 91 | .sym_num = SYM_NUM, |
92 | .ocon_num = OCON_NUM, | 92 | .ocon_num = OCON_NUM, |
93 | }, | 93 | }, |
94 | { | ||
95 | .version = POLICYDB_VERSION_AVTAB, | ||
96 | .sym_num = SYM_NUM, | ||
97 | .ocon_num = OCON_NUM, | ||
98 | }, | ||
94 | }; | 99 | }; |
95 | 100 | ||
96 | static struct policydb_compat_info *policydb_lookup_compat(int version) | 101 | static struct policydb_compat_info *policydb_lookup_compat(int version) |
@@ -584,6 +589,9 @@ void policydb_destroy(struct policydb *p) | |||
584 | struct ocontext *c, *ctmp; | 589 | struct ocontext *c, *ctmp; |
585 | struct genfs *g, *gtmp; | 590 | struct genfs *g, *gtmp; |
586 | int i; | 591 | int i; |
592 | struct role_allow *ra, *lra = NULL; | ||
593 | struct role_trans *tr, *ltr = NULL; | ||
594 | struct range_trans *rt, *lrt = NULL; | ||
587 | 595 | ||
588 | for (i = 0; i < SYM_NUM; i++) { | 596 | for (i = 0; i < SYM_NUM; i++) { |
589 | hashtab_map(p->symtab[i].table, destroy_f[i], NULL); | 597 | hashtab_map(p->symtab[i].table, destroy_f[i], NULL); |
@@ -624,6 +632,28 @@ void policydb_destroy(struct policydb *p) | |||
624 | 632 | ||
625 | cond_policydb_destroy(p); | 633 | cond_policydb_destroy(p); |
626 | 634 | ||
635 | for (tr = p->role_tr; tr; tr = tr->next) { | ||
636 | if (ltr) kfree(ltr); | ||
637 | ltr = tr; | ||
638 | } | ||
639 | if (ltr) kfree(ltr); | ||
640 | |||
641 | for (ra = p->role_allow; ra; ra = ra -> next) { | ||
642 | if (lra) kfree(lra); | ||
643 | lra = ra; | ||
644 | } | ||
645 | if (lra) kfree(lra); | ||
646 | |||
647 | for (rt = p->range_tr; rt; rt = rt -> next) { | ||
648 | if (lrt) kfree(lrt); | ||
649 | lrt = rt; | ||
650 | } | ||
651 | if (lrt) kfree(lrt); | ||
652 | |||
653 | for (i = 0; i < p->p_types.nprim; i++) | ||
654 | ebitmap_destroy(&p->type_attr_map[i]); | ||
655 | kfree(p->type_attr_map); | ||
656 | |||
627 | return; | 657 | return; |
628 | } | 658 | } |
629 | 659 | ||
@@ -1511,7 +1541,7 @@ int policydb_read(struct policydb *p, void *fp) | |||
1511 | p->symtab[i].nprim = nprim; | 1541 | p->symtab[i].nprim = nprim; |
1512 | } | 1542 | } |
1513 | 1543 | ||
1514 | rc = avtab_read(&p->te_avtab, fp, config); | 1544 | rc = avtab_read(&p->te_avtab, fp, p->policyvers); |
1515 | if (rc) | 1545 | if (rc) |
1516 | goto bad; | 1546 | goto bad; |
1517 | 1547 | ||
@@ -1825,6 +1855,21 @@ int policydb_read(struct policydb *p, void *fp) | |||
1825 | } | 1855 | } |
1826 | } | 1856 | } |
1827 | 1857 | ||
1858 | p->type_attr_map = kmalloc(p->p_types.nprim*sizeof(struct ebitmap), GFP_KERNEL); | ||
1859 | if (!p->type_attr_map) | ||
1860 | goto bad; | ||
1861 | |||
1862 | for (i = 0; i < p->p_types.nprim; i++) { | ||
1863 | ebitmap_init(&p->type_attr_map[i]); | ||
1864 | if (p->policyvers >= POLICYDB_VERSION_AVTAB) { | ||
1865 | if (ebitmap_read(&p->type_attr_map[i], fp)) | ||
1866 | goto bad; | ||
1867 | } | ||
1868 | /* add the type itself as the degenerate case */ | ||
1869 | if (ebitmap_set_bit(&p->type_attr_map[i], i, 1)) | ||
1870 | goto bad; | ||
1871 | } | ||
1872 | |||
1828 | rc = 0; | 1873 | rc = 0; |
1829 | out: | 1874 | out: |
1830 | return rc; | 1875 | return rc; |