aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss
diff options
context:
space:
mode:
authorEric Paris <eparis@redhat.com>2011-04-28 15:11:21 -0400
committerEric Paris <eparis@redhat.com>2011-04-28 15:15:52 -0400
commit03a4c0182a156547edd5f2717c1702590fe36bbf (patch)
treec4585fab7c37d4eb2cc46e93c925e7c2a5e7b1a2 /security/selinux/ss
parent2667991f60e67d28c495b8967aaabf84b4ccd560 (diff)
SELinux: skip filename trans rules if ttype does not match parent dir
Right now we walk to filename trans rule list for every inode that is created. First passes at policy using this facility creates around 5000 filename trans rules. Running a list of 5000 entries every time is a bad idea. This patch adds a new ebitmap to policy which has a bit set for each ttype that has at least 1 filename trans rule. Thus when an inode is created we can quickly determine if any rules exist for this parent directory type and can skip the list if we know there is definitely no relevant entry. Signed-off-by: Eric Paris <eparis@redhat.com> Reviewed-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/ss')
-rw-r--r--security/selinux/ss/policydb.c6
-rw-r--r--security/selinux/ss/policydb.h2
-rw-r--r--security/selinux/ss/services.c9
3 files changed, 17 insertions, 0 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 5591e422256a..4c1811972b8b 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -240,6 +240,7 @@ static int policydb_init(struct policydb *p)
240 if (!p->range_tr) 240 if (!p->range_tr)
241 goto out; 241 goto out;
242 242
243 ebitmap_init(&p->filename_trans_ttypes);
243 ebitmap_init(&p->policycaps); 244 ebitmap_init(&p->policycaps);
244 ebitmap_init(&p->permissive_map); 245 ebitmap_init(&p->permissive_map);
245 246
@@ -801,6 +802,7 @@ void policydb_destroy(struct policydb *p)
801 ft = nft; 802 ft = nft;
802 } 803 }
803 804
805 ebitmap_destroy(&p->filename_trans_ttypes);
804 ebitmap_destroy(&p->policycaps); 806 ebitmap_destroy(&p->policycaps);
805 ebitmap_destroy(&p->permissive_map); 807 ebitmap_destroy(&p->permissive_map);
806 808
@@ -1868,6 +1870,10 @@ static int filename_trans_read(struct policydb *p, void *fp)
1868 ft->ttype = le32_to_cpu(buf[1]); 1870 ft->ttype = le32_to_cpu(buf[1]);
1869 ft->tclass = le32_to_cpu(buf[2]); 1871 ft->tclass = le32_to_cpu(buf[2]);
1870 ft->otype = le32_to_cpu(buf[3]); 1872 ft->otype = le32_to_cpu(buf[3]);
1873
1874 rc = ebitmap_set_bit(&p->filename_trans_ttypes, ft->ttype, 1);
1875 if (rc)
1876 goto out;
1871 } 1877 }
1872 rc = 0; 1878 rc = 0;
1873out: 1879out:
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 801175f79cf9..f054a9d4d114 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -227,6 +227,8 @@ struct policydb {
227 /* role transitions */ 227 /* role transitions */
228 struct role_trans *role_tr; 228 struct role_trans *role_tr;
229 229
230 /* quickly exclude lookups when parent ttype has no rules */
231 struct ebitmap filename_trans_ttypes;
230 /* file transitions with the last path component */ 232 /* file transitions with the last path component */
231 struct filename_trans *filename_trans; 233 struct filename_trans *filename_trans;
232 234
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 78bb8100b02e..6a22eaebf3b7 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1363,6 +1363,15 @@ static void filename_compute_type(struct policydb *p, struct context *newcontext
1363 const char *objname) 1363 const char *objname)
1364{ 1364{
1365 struct filename_trans *ft; 1365 struct filename_trans *ft;
1366
1367 /*
1368 * Most filename trans rules are going to live in specific directories
1369 * like /dev or /var/run. This bitmap will quickly skip rule searches
1370 * if the ttype does not contain any rules.
1371 */
1372 if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype))
1373 return;
1374
1366 for (ft = p->filename_trans; ft; ft = ft->next) { 1375 for (ft = p->filename_trans; ft; ft = ft->next) {
1367 if (ft->stype == stype && 1376 if (ft->stype == stype &&
1368 ft->ttype == ttype && 1377 ft->ttype == ttype &&