aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2011-05-24 09:20:19 -0400
committerJames Morris <jmorris@namei.org>2011-05-24 09:20:19 -0400
commitb7b57551bbda1390959207f79f2038aa7adb72ae (patch)
treed591a08e7e45615b51d8b5ee1634a29920f62c3f /security/selinux/ss
parent434d42cfd05a7cc452457a81d2029540cba12150 (diff)
parent7a627e3b9a2bd0f06945bbe64bcf403e788ecf6e (diff)
Merge branch 'master' of git://git.infradead.org/users/eparis/selinux into for-linus
Conflicts: lib/flex_array.c security/selinux/avc.c security/selinux/hooks.c security/selinux/ss/policydb.c security/smack/smack_lsm.c Manually resolve conflicts. Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/ss')
-rw-r--r--security/selinux/ss/policydb.c244
-rw-r--r--security/selinux/ss/policydb.h12
-rw-r--r--security/selinux/ss/services.c72
3 files changed, 217 insertions, 111 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 7102457661d6..102e9ec1b77a 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -128,6 +128,11 @@ static struct policydb_compat_info policydb_compat[] = {
128 .sym_num = SYM_NUM, 128 .sym_num = SYM_NUM,
129 .ocon_num = OCON_NUM, 129 .ocon_num = OCON_NUM,
130 }, 130 },
131 {
132 .version = POLICYDB_VERSION_ROLETRANS,
133 .sym_num = SYM_NUM,
134 .ocon_num = OCON_NUM,
135 },
131}; 136};
132 137
133static struct policydb_compat_info *policydb_lookup_compat(int version) 138static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -179,6 +184,43 @@ out:
179 return rc; 184 return rc;
180} 185}
181 186
187static u32 filenametr_hash(struct hashtab *h, const void *k)
188{
189 const struct filename_trans *ft = k;
190 unsigned long hash;
191 unsigned int byte_num;
192 unsigned char focus;
193
194 hash = ft->stype ^ ft->ttype ^ ft->tclass;
195
196 byte_num = 0;
197 while ((focus = ft->name[byte_num++]))
198 hash = partial_name_hash(focus, hash);
199 return hash & (h->size - 1);
200}
201
202static int filenametr_cmp(struct hashtab *h, const void *k1, const void *k2)
203{
204 const struct filename_trans *ft1 = k1;
205 const struct filename_trans *ft2 = k2;
206 int v;
207
208 v = ft1->stype - ft2->stype;
209 if (v)
210 return v;
211
212 v = ft1->ttype - ft2->ttype;
213 if (v)
214 return v;
215
216 v = ft1->tclass - ft2->tclass;
217 if (v)
218 return v;
219
220 return strcmp(ft1->name, ft2->name);
221
222}
223
182static u32 rangetr_hash(struct hashtab *h, const void *k) 224static u32 rangetr_hash(struct hashtab *h, const void *k)
183{ 225{
184 const struct range_trans *key = k; 226 const struct range_trans *key = k;
@@ -231,15 +273,22 @@ static int policydb_init(struct policydb *p)
231 if (rc) 273 if (rc)
232 goto out; 274 goto out;
233 275
276 p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
277 if (!p->filename_trans)
278 goto out;
279
234 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); 280 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
235 if (!p->range_tr) 281 if (!p->range_tr)
236 goto out; 282 goto out;
237 283
284 ebitmap_init(&p->filename_trans_ttypes);
238 ebitmap_init(&p->policycaps); 285 ebitmap_init(&p->policycaps);
239 ebitmap_init(&p->permissive_map); 286 ebitmap_init(&p->permissive_map);
240 287
241 return 0; 288 return 0;
242out: 289out:
290 hashtab_destroy(p->filename_trans);
291 hashtab_destroy(p->range_tr);
243 for (i = 0; i < SYM_NUM; i++) 292 for (i = 0; i < SYM_NUM; i++)
244 hashtab_destroy(p->symtab[i].table); 293 hashtab_destroy(p->symtab[i].table);
245 return rc; 294 return rc;
@@ -417,32 +466,26 @@ static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
417}; 466};
418 467
419#ifdef DEBUG_HASHES 468#ifdef DEBUG_HASHES
420static void symtab_hash_eval(struct symtab *s) 469static void hash_eval(struct hashtab *h, const char *hash_name)
421{ 470{
422 int i; 471 struct hashtab_info info;
423
424 for (i = 0; i < SYM_NUM; i++) {
425 struct hashtab *h = s[i].table;
426 struct hashtab_info info;
427 472
428 hashtab_stat(h, &info); 473 hashtab_stat(h, &info);
429 printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, " 474 printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, "
430 "longest chain length %d\n", symtab_name[i], h->nel, 475 "longest chain length %d\n", hash_name, h->nel,
431 info.slots_used, h->size, info.max_chain_len); 476 info.slots_used, h->size, info.max_chain_len);
432 }
433} 477}
434 478
435static void rangetr_hash_eval(struct hashtab *h) 479static void symtab_hash_eval(struct symtab *s)
436{ 480{
437 struct hashtab_info info; 481 int i;
438 482
439 hashtab_stat(h, &info); 483 for (i = 0; i < SYM_NUM; i++)
440 printk(KERN_DEBUG "SELinux: rangetr: %d entries and %d/%d buckets used, " 484 hash_eval(s[i].table, symtab_name[i]);
441 "longest chain length %d\n", h->nel,
442 info.slots_used, h->size, info.max_chain_len);
443} 485}
486
444#else 487#else
445static inline void rangetr_hash_eval(struct hashtab *h) 488static inline void hash_eval(struct hashtab *h, char *hash_name)
446{ 489{
447} 490}
448#endif 491#endif
@@ -675,6 +718,16 @@ static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
675 cat_destroy, 718 cat_destroy,
676}; 719};
677 720
721static int filenametr_destroy(void *key, void *datum, void *p)
722{
723 struct filename_trans *ft = key;
724 kfree(ft->name);
725 kfree(key);
726 kfree(datum);
727 cond_resched();
728 return 0;
729}
730
678static int range_tr_destroy(void *key, void *datum, void *p) 731static int range_tr_destroy(void *key, void *datum, void *p)
679{ 732{
680 struct mls_range *rt = datum; 733 struct mls_range *rt = datum;
@@ -709,7 +762,6 @@ void policydb_destroy(struct policydb *p)
709 int i; 762 int i;
710 struct role_allow *ra, *lra = NULL; 763 struct role_allow *ra, *lra = NULL;
711 struct role_trans *tr, *ltr = NULL; 764 struct role_trans *tr, *ltr = NULL;
712 struct filename_trans *ft, *nft;
713 765
714 for (i = 0; i < SYM_NUM; i++) { 766 for (i = 0; i < SYM_NUM; i++) {
715 cond_resched(); 767 cond_resched();
@@ -773,6 +825,9 @@ void policydb_destroy(struct policydb *p)
773 } 825 }
774 kfree(lra); 826 kfree(lra);
775 827
828 hashtab_map(p->filename_trans, filenametr_destroy, NULL);
829 hashtab_destroy(p->filename_trans);
830
776 hashtab_map(p->range_tr, range_tr_destroy, NULL); 831 hashtab_map(p->range_tr, range_tr_destroy, NULL);
777 hashtab_destroy(p->range_tr); 832 hashtab_destroy(p->range_tr);
778 833
@@ -788,14 +843,7 @@ void policydb_destroy(struct policydb *p)
788 flex_array_free(p->type_attr_map_array); 843 flex_array_free(p->type_attr_map_array);
789 } 844 }
790 845
791 ft = p->filename_trans; 846 ebitmap_destroy(&p->filename_trans_ttypes);
792 while (ft) {
793 nft = ft->next;
794 kfree(ft->name);
795 kfree(ft);
796 ft = nft;
797 }
798
799 ebitmap_destroy(&p->policycaps); 847 ebitmap_destroy(&p->policycaps);
800 ebitmap_destroy(&p->permissive_map); 848 ebitmap_destroy(&p->permissive_map);
801 849
@@ -1795,7 +1843,7 @@ static int range_read(struct policydb *p, void *fp)
1795 rt = NULL; 1843 rt = NULL;
1796 r = NULL; 1844 r = NULL;
1797 } 1845 }
1798 rangetr_hash_eval(p->range_tr); 1846 hash_eval(p->range_tr, "rangetr");
1799 rc = 0; 1847 rc = 0;
1800out: 1848out:
1801 kfree(rt); 1849 kfree(rt);
@@ -1805,9 +1853,10 @@ out:
1805 1853
1806static int filename_trans_read(struct policydb *p, void *fp) 1854static int filename_trans_read(struct policydb *p, void *fp)
1807{ 1855{
1808 struct filename_trans *ft, *last; 1856 struct filename_trans *ft;
1809 u32 nel, len; 1857 struct filename_trans_datum *otype;
1810 char *name; 1858 char *name;
1859 u32 nel, len;
1811 __le32 buf[4]; 1860 __le32 buf[4];
1812 int rc, i; 1861 int rc, i;
1813 1862
@@ -1816,25 +1865,23 @@ static int filename_trans_read(struct policydb *p, void *fp)
1816 1865
1817 rc = next_entry(buf, fp, sizeof(u32)); 1866 rc = next_entry(buf, fp, sizeof(u32));
1818 if (rc) 1867 if (rc)
1819 goto out; 1868 return rc;
1820 nel = le32_to_cpu(buf[0]); 1869 nel = le32_to_cpu(buf[0]);
1821 1870
1822 last = p->filename_trans;
1823 while (last && last->next)
1824 last = last->next;
1825
1826 for (i = 0; i < nel; i++) { 1871 for (i = 0; i < nel; i++) {
1872 ft = NULL;
1873 otype = NULL;
1874 name = NULL;
1875
1827 rc = -ENOMEM; 1876 rc = -ENOMEM;
1828 ft = kzalloc(sizeof(*ft), GFP_KERNEL); 1877 ft = kzalloc(sizeof(*ft), GFP_KERNEL);
1829 if (!ft) 1878 if (!ft)
1830 goto out; 1879 goto out;
1831 1880
1832 /* add it to the tail of the list */ 1881 rc = -ENOMEM;
1833 if (!last) 1882 otype = kmalloc(sizeof(*otype), GFP_KERNEL);
1834 p->filename_trans = ft; 1883 if (!otype)
1835 else 1884 goto out;
1836 last->next = ft;
1837 last = ft;
1838 1885
1839 /* length of the path component string */ 1886 /* length of the path component string */
1840 rc = next_entry(buf, fp, sizeof(u32)); 1887 rc = next_entry(buf, fp, sizeof(u32));
@@ -1862,10 +1909,22 @@ static int filename_trans_read(struct policydb *p, void *fp)
1862 ft->stype = le32_to_cpu(buf[0]); 1909 ft->stype = le32_to_cpu(buf[0]);
1863 ft->ttype = le32_to_cpu(buf[1]); 1910 ft->ttype = le32_to_cpu(buf[1]);
1864 ft->tclass = le32_to_cpu(buf[2]); 1911 ft->tclass = le32_to_cpu(buf[2]);
1865 ft->otype = le32_to_cpu(buf[3]); 1912
1913 otype->otype = le32_to_cpu(buf[3]);
1914
1915 rc = ebitmap_set_bit(&p->filename_trans_ttypes, ft->ttype, 1);
1916 if (rc)
1917 goto out;
1918
1919 hashtab_insert(p->filename_trans, ft, otype);
1866 } 1920 }
1867 rc = 0; 1921 hash_eval(p->filename_trans, "filenametr");
1922 return 0;
1868out: 1923out:
1924 kfree(ft);
1925 kfree(name);
1926 kfree(otype);
1927
1869 return rc; 1928 return rc;
1870} 1929}
1871 1930
@@ -2266,6 +2325,11 @@ int policydb_read(struct policydb *p, void *fp)
2266 p->symtab[i].nprim = nprim; 2325 p->symtab[i].nprim = nprim;
2267 } 2326 }
2268 2327
2328 rc = -EINVAL;
2329 p->process_class = string_to_security_class(p, "process");
2330 if (!p->process_class)
2331 goto bad;
2332
2269 rc = avtab_read(&p->te_avtab, fp, p); 2333 rc = avtab_read(&p->te_avtab, fp, p);
2270 if (rc) 2334 if (rc)
2271 goto bad; 2335 goto bad;
@@ -2298,8 +2362,17 @@ int policydb_read(struct policydb *p, void *fp)
2298 tr->role = le32_to_cpu(buf[0]); 2362 tr->role = le32_to_cpu(buf[0]);
2299 tr->type = le32_to_cpu(buf[1]); 2363 tr->type = le32_to_cpu(buf[1]);
2300 tr->new_role = le32_to_cpu(buf[2]); 2364 tr->new_role = le32_to_cpu(buf[2]);
2365 if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2366 rc = next_entry(buf, fp, sizeof(u32));
2367 if (rc)
2368 goto bad;
2369 tr->tclass = le32_to_cpu(buf[0]);
2370 } else
2371 tr->tclass = p->process_class;
2372
2301 if (!policydb_role_isvalid(p, tr->role) || 2373 if (!policydb_role_isvalid(p, tr->role) ||
2302 !policydb_type_isvalid(p, tr->type) || 2374 !policydb_type_isvalid(p, tr->type) ||
2375 !policydb_class_isvalid(p, tr->tclass) ||
2303 !policydb_role_isvalid(p, tr->new_role)) 2376 !policydb_role_isvalid(p, tr->new_role))
2304 goto bad; 2377 goto bad;
2305 ltr = tr; 2378 ltr = tr;
@@ -2341,11 +2414,6 @@ int policydb_read(struct policydb *p, void *fp)
2341 goto bad; 2414 goto bad;
2342 2415
2343 rc = -EINVAL; 2416 rc = -EINVAL;
2344 p->process_class = string_to_security_class(p, "process");
2345 if (!p->process_class)
2346 goto bad;
2347
2348 rc = -EINVAL;
2349 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition"); 2417 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
2350 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition"); 2418 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
2351 if (!p->process_trans_perms) 2419 if (!p->process_trans_perms)
@@ -2517,8 +2585,9 @@ static int cat_write(void *vkey, void *datum, void *ptr)
2517 return 0; 2585 return 0;
2518} 2586}
2519 2587
2520static int role_trans_write(struct role_trans *r, void *fp) 2588static int role_trans_write(struct policydb *p, void *fp)
2521{ 2589{
2590 struct role_trans *r = p->role_tr;
2522 struct role_trans *tr; 2591 struct role_trans *tr;
2523 u32 buf[3]; 2592 u32 buf[3];
2524 size_t nel; 2593 size_t nel;
@@ -2538,6 +2607,12 @@ static int role_trans_write(struct role_trans *r, void *fp)
2538 rc = put_entry(buf, sizeof(u32), 3, fp); 2607 rc = put_entry(buf, sizeof(u32), 3, fp);
2539 if (rc) 2608 if (rc)
2540 return rc; 2609 return rc;
2610 if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2611 buf[0] = cpu_to_le32(tr->tclass);
2612 rc = put_entry(buf, sizeof(u32), 1, fp);
2613 if (rc)
2614 return rc;
2615 }
2541 } 2616 }
2542 2617
2543 return 0; 2618 return 0;
@@ -3045,7 +3120,7 @@ static int genfs_write(struct policydb *p, void *fp)
3045 return 0; 3120 return 0;
3046} 3121}
3047 3122
3048static int range_count(void *key, void *data, void *ptr) 3123static int hashtab_cnt(void *key, void *data, void *ptr)
3049{ 3124{
3050 int *cnt = ptr; 3125 int *cnt = ptr;
3051 *cnt = *cnt + 1; 3126 *cnt = *cnt + 1;
@@ -3093,7 +3168,7 @@ static int range_write(struct policydb *p, void *fp)
3093 3168
3094 /* count the number of entries in the hashtab */ 3169 /* count the number of entries in the hashtab */
3095 nel = 0; 3170 nel = 0;
3096 rc = hashtab_map(p->range_tr, range_count, &nel); 3171 rc = hashtab_map(p->range_tr, hashtab_cnt, &nel);
3097 if (rc) 3172 if (rc)
3098 return rc; 3173 return rc;
3099 3174
@@ -3110,43 +3185,60 @@ static int range_write(struct policydb *p, void *fp)
3110 return 0; 3185 return 0;
3111} 3186}
3112 3187
3113static int filename_trans_write(struct policydb *p, void *fp) 3188static int filename_write_helper(void *key, void *data, void *ptr)
3114{ 3189{
3115 struct filename_trans *ft;
3116 u32 len, nel = 0;
3117 __le32 buf[4]; 3190 __le32 buf[4];
3191 struct filename_trans *ft = key;
3192 struct filename_trans_datum *otype = data;
3193 void *fp = ptr;
3118 int rc; 3194 int rc;
3195 u32 len;
3119 3196
3120 for (ft = p->filename_trans; ft; ft = ft->next) 3197 len = strlen(ft->name);
3121 nel++; 3198 buf[0] = cpu_to_le32(len);
3122
3123 buf[0] = cpu_to_le32(nel);
3124 rc = put_entry(buf, sizeof(u32), 1, fp); 3199 rc = put_entry(buf, sizeof(u32), 1, fp);
3125 if (rc) 3200 if (rc)
3126 return rc; 3201 return rc;
3127 3202
3128 for (ft = p->filename_trans; ft; ft = ft->next) { 3203 rc = put_entry(ft->name, sizeof(char), len, fp);
3129 len = strlen(ft->name); 3204 if (rc)
3130 buf[0] = cpu_to_le32(len); 3205 return rc;
3131 rc = put_entry(buf, sizeof(u32), 1, fp);
3132 if (rc)
3133 return rc;
3134 3206
3135 rc = put_entry(ft->name, sizeof(char), len, fp); 3207 buf[0] = ft->stype;
3136 if (rc) 3208 buf[1] = ft->ttype;
3137 return rc; 3209 buf[2] = ft->tclass;
3210 buf[3] = otype->otype;
3138 3211
3139 buf[0] = ft->stype; 3212 rc = put_entry(buf, sizeof(u32), 4, fp);
3140 buf[1] = ft->ttype; 3213 if (rc)
3141 buf[2] = ft->tclass; 3214 return rc;
3142 buf[3] = ft->otype;
3143 3215
3144 rc = put_entry(buf, sizeof(u32), 4, fp);
3145 if (rc)
3146 return rc;
3147 }
3148 return 0; 3216 return 0;
3149} 3217}
3218
3219static int filename_trans_write(struct policydb *p, void *fp)
3220{
3221 u32 nel;
3222 __le32 buf[1];
3223 int rc;
3224
3225 nel = 0;
3226 rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel);
3227 if (rc)
3228 return rc;
3229
3230 buf[0] = cpu_to_le32(nel);
3231 rc = put_entry(buf, sizeof(u32), 1, fp);
3232 if (rc)
3233 return rc;
3234
3235 rc = hashtab_map(p->filename_trans, filename_write_helper, fp);
3236 if (rc)
3237 return rc;
3238
3239 return 0;
3240}
3241
3150/* 3242/*
3151 * Write the configuration data in a policy database 3243 * Write the configuration data in a policy database
3152 * structure to a policy database binary representation 3244 * structure to a policy database binary representation
@@ -3249,7 +3341,7 @@ int policydb_write(struct policydb *p, void *fp)
3249 if (rc) 3341 if (rc)
3250 return rc; 3342 return rc;
3251 3343
3252 rc = role_trans_write(p->role_tr, fp); 3344 rc = role_trans_write(p, fp);
3253 if (rc) 3345 if (rc)
3254 return rc; 3346 return rc;
3255 3347
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 732ea4a68682..b846c0387180 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -72,17 +72,20 @@ struct role_datum {
72 72
73struct role_trans { 73struct role_trans {
74 u32 role; /* current role */ 74 u32 role; /* current role */
75 u32 type; /* program executable type */ 75 u32 type; /* program executable type, or new object type */
76 u32 tclass; /* process class, or new object class */
76 u32 new_role; /* new role */ 77 u32 new_role; /* new role */
77 struct role_trans *next; 78 struct role_trans *next;
78}; 79};
79 80
80struct filename_trans { 81struct filename_trans {
81 struct filename_trans *next;
82 u32 stype; /* current process */ 82 u32 stype; /* current process */
83 u32 ttype; /* parent dir context */ 83 u32 ttype; /* parent dir context */
84 u16 tclass; /* class of new object */ 84 u16 tclass; /* class of new object */
85 const char *name; /* last path component */ 85 const char *name; /* last path component */
86};
87
88struct filename_trans_datum {
86 u32 otype; /* expected of new object */ 89 u32 otype; /* expected of new object */
87}; 90};
88 91
@@ -227,7 +230,10 @@ struct policydb {
227 struct role_trans *role_tr; 230 struct role_trans *role_tr;
228 231
229 /* file transitions with the last path component */ 232 /* file transitions with the last path component */
230 struct filename_trans *filename_trans; 233 /* quickly exclude lookups when parent ttype has no rules */
234 struct ebitmap filename_trans_ttypes;
235 /* actual set of filename_trans rules */
236 struct hashtab *filename_trans;
231 237
232 /* bools indexed by (value - 1) */ 238 /* bools indexed by (value - 1) */
233 struct cond_bool_datum **bool_val_to_struct; 239 struct cond_bool_datum **bool_val_to_struct;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 6ef4af47dac4..c3e4b52699f4 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1359,26 +1359,35 @@ out:
1359} 1359}
1360 1360
1361static void filename_compute_type(struct policydb *p, struct context *newcontext, 1361static void filename_compute_type(struct policydb *p, struct context *newcontext,
1362 u32 scon, u32 tcon, u16 tclass, 1362 u32 stype, u32 ttype, u16 tclass,
1363 const struct qstr *qstr) 1363 const char *objname)
1364{ 1364{
1365 struct filename_trans *ft; 1365 struct filename_trans ft;
1366 for (ft = p->filename_trans; ft; ft = ft->next) { 1366 struct filename_trans_datum *otype;
1367 if (ft->stype == scon && 1367
1368 ft->ttype == tcon && 1368 /*
1369 ft->tclass == tclass && 1369 * Most filename trans rules are going to live in specific directories
1370 !strcmp(ft->name, qstr->name)) { 1370 * like /dev or /var/run. This bitmap will quickly skip rule searches
1371 newcontext->type = ft->otype; 1371 * if the ttype does not contain any rules.
1372 return; 1372 */
1373 } 1373 if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype))
1374 } 1374 return;
1375
1376 ft.stype = stype;
1377 ft.ttype = ttype;
1378 ft.tclass = tclass;
1379 ft.name = objname;
1380
1381 otype = hashtab_search(p->filename_trans, &ft);
1382 if (otype)
1383 newcontext->type = otype->otype;
1375} 1384}
1376 1385
1377static int security_compute_sid(u32 ssid, 1386static int security_compute_sid(u32 ssid,
1378 u32 tsid, 1387 u32 tsid,
1379 u16 orig_tclass, 1388 u16 orig_tclass,
1380 u32 specified, 1389 u32 specified,
1381 const struct qstr *qstr, 1390 const char *objname,
1382 u32 *out_sid, 1391 u32 *out_sid,
1383 bool kern) 1392 bool kern)
1384{ 1393{
@@ -1478,23 +1487,21 @@ static int security_compute_sid(u32 ssid,
1478 newcontext.type = avdatum->data; 1487 newcontext.type = avdatum->data;
1479 } 1488 }
1480 1489
1481 /* if we have a qstr this is a file trans check so check those rules */ 1490 /* if we have a objname this is a file trans check so check those rules */
1482 if (qstr) 1491 if (objname)
1483 filename_compute_type(&policydb, &newcontext, scontext->type, 1492 filename_compute_type(&policydb, &newcontext, scontext->type,
1484 tcontext->type, tclass, qstr); 1493 tcontext->type, tclass, objname);
1485 1494
1486 /* Check for class-specific changes. */ 1495 /* Check for class-specific changes. */
1487 if (tclass == policydb.process_class) { 1496 if (specified & AVTAB_TRANSITION) {
1488 if (specified & AVTAB_TRANSITION) { 1497 /* Look for a role transition rule. */
1489 /* Look for a role transition rule. */ 1498 for (roletr = policydb.role_tr; roletr; roletr = roletr->next) {
1490 for (roletr = policydb.role_tr; roletr; 1499 if ((roletr->role == scontext->role) &&
1491 roletr = roletr->next) { 1500 (roletr->type == tcontext->type) &&
1492 if (roletr->role == scontext->role && 1501 (roletr->tclass == tclass)) {
1493 roletr->type == tcontext->type) { 1502 /* Use the role transition rule. */
1494 /* Use the role transition rule. */ 1503 newcontext.role = roletr->new_role;
1495 newcontext.role = roletr->new_role; 1504 break;
1496 break;
1497 }
1498 } 1505 }
1499 } 1506 }
1500 } 1507 }
@@ -1541,13 +1548,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
1541 const struct qstr *qstr, u32 *out_sid) 1548 const struct qstr *qstr, u32 *out_sid)
1542{ 1549{
1543 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, 1550 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1544 qstr, out_sid, true); 1551 qstr ? qstr->name : NULL, out_sid, true);
1545} 1552}
1546 1553
1547int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) 1554int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
1555 const char *objname, u32 *out_sid)
1548{ 1556{
1549 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, 1557 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1550 NULL, out_sid, false); 1558 objname, out_sid, false);
1551} 1559}
1552 1560
1553/** 1561/**
@@ -3190,7 +3198,7 @@ out:
3190 * @len: length of data in bytes 3198 * @len: length of data in bytes
3191 * 3199 *
3192 */ 3200 */
3193int security_read_policy(void **data, ssize_t *len) 3201int security_read_policy(void **data, size_t *len)
3194{ 3202{
3195 int rc; 3203 int rc;
3196 struct policy_file fp; 3204 struct policy_file fp;