~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to security/selinux/ss/policydb.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
123
123
                .sym_num        = SYM_NUM,
124
124
                .ocon_num       = OCON_NUM,
125
125
        },
 
126
        {
 
127
                .version        = POLICYDB_VERSION_FILENAME_TRANS,
 
128
                .sym_num        = SYM_NUM,
 
129
                .ocon_num       = OCON_NUM,
 
130
        },
 
131
        {
 
132
                .version        = POLICYDB_VERSION_ROLETRANS,
 
133
                .sym_num        = SYM_NUM,
 
134
                .ocon_num       = OCON_NUM,
 
135
        },
126
136
};
127
137
 
128
138
static struct policydb_compat_info *policydb_lookup_compat(int version)
174
184
        return rc;
175
185
}
176
186
 
 
187
static 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
 
 
202
static 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
 
177
224
static u32 rangetr_hash(struct hashtab *h, const void *k)
178
225
{
179
226
        const struct range_trans *key = k;
226
273
        if (rc)
227
274
                goto out;
228
275
 
 
276
        p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
 
277
        if (!p->filename_trans)
 
278
                goto out;
 
279
 
229
280
        p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
230
281
        if (!p->range_tr)
231
282
                goto out;
232
283
 
 
284
        ebitmap_init(&p->filename_trans_ttypes);
233
285
        ebitmap_init(&p->policycaps);
234
286
        ebitmap_init(&p->permissive_map);
235
287
 
236
288
        return 0;
237
289
out:
 
290
        hashtab_destroy(p->filename_trans);
 
291
        hashtab_destroy(p->range_tr);
238
292
        for (i = 0; i < SYM_NUM; i++)
239
293
                hashtab_destroy(p->symtab[i].table);
240
294
        return rc;
412
466
};
413
467
 
414
468
#ifdef DEBUG_HASHES
415
 
static void symtab_hash_eval(struct symtab *s)
416
 
{
417
 
        int i;
418
 
 
419
 
        for (i = 0; i < SYM_NUM; i++) {
420
 
                struct hashtab *h = s[i].table;
421
 
                struct hashtab_info info;
422
 
 
423
 
                hashtab_stat(h, &info);
424
 
                printk(KERN_DEBUG "SELinux: %s:  %d entries and %d/%d buckets used, "
425
 
                       "longest chain length %d\n", symtab_name[i], h->nel,
426
 
                       info.slots_used, h->size, info.max_chain_len);
427
 
        }
428
 
}
429
 
 
430
 
static void rangetr_hash_eval(struct hashtab *h)
 
469
static void hash_eval(struct hashtab *h, const char *hash_name)
431
470
{
432
471
        struct hashtab_info info;
433
472
 
434
473
        hashtab_stat(h, &info);
435
 
        printk(KERN_DEBUG "SELinux: rangetr:  %d entries and %d/%d buckets used, "
436
 
               "longest chain length %d\n", h->nel,
 
474
        printk(KERN_DEBUG "SELinux: %s:  %d entries and %d/%d buckets used, "
 
475
               "longest chain length %d\n", hash_name, h->nel,
437
476
               info.slots_used, h->size, info.max_chain_len);
438
477
}
 
478
 
 
479
static void symtab_hash_eval(struct symtab *s)
 
480
{
 
481
        int i;
 
482
 
 
483
        for (i = 0; i < SYM_NUM; i++)
 
484
                hash_eval(s[i].table, symtab_name[i]);
 
485
}
 
486
 
439
487
#else
440
 
static inline void rangetr_hash_eval(struct hashtab *h)
 
488
static inline void hash_eval(struct hashtab *h, char *hash_name)
441
489
{
442
490
}
443
491
#endif
497
545
                goto out;
498
546
 
499
547
        rc = flex_array_prealloc(p->type_val_to_struct_array, 0,
500
 
                                 p->p_types.nprim - 1, GFP_KERNEL | __GFP_ZERO);
 
548
                                 p->p_types.nprim, GFP_KERNEL | __GFP_ZERO);
501
549
        if (rc)
502
550
                goto out;
503
551
 
514
562
                        goto out;
515
563
 
516
564
                rc = flex_array_prealloc(p->sym_val_to_name[i],
517
 
                                         0, p->symtab[i].nprim - 1,
 
565
                                         0, p->symtab[i].nprim,
518
566
                                         GFP_KERNEL | __GFP_ZERO);
519
567
                if (rc)
520
568
                        goto out;
670
718
        cat_destroy,
671
719
};
672
720
 
 
721
static 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
 
673
731
static int range_tr_destroy(void *key, void *datum, void *p)
674
732
{
675
733
        struct mls_range *rt = datum;
767
825
        }
768
826
        kfree(lra);
769
827
 
 
828
        hashtab_map(p->filename_trans, filenametr_destroy, NULL);
 
829
        hashtab_destroy(p->filename_trans);
 
830
 
770
831
        hashtab_map(p->range_tr, range_tr_destroy, NULL);
771
832
        hashtab_destroy(p->range_tr);
772
833
 
781
842
                }
782
843
                flex_array_free(p->type_attr_map_array);
783
844
        }
 
845
 
 
846
        ebitmap_destroy(&p->filename_trans_ttypes);
784
847
        ebitmap_destroy(&p->policycaps);
785
848
        ebitmap_destroy(&p->permissive_map);
786
849
 
1780
1843
                rt = NULL;
1781
1844
                r = NULL;
1782
1845
        }
1783
 
        rangetr_hash_eval(p->range_tr);
 
1846
        hash_eval(p->range_tr, "rangetr");
1784
1847
        rc = 0;
1785
1848
out:
1786
1849
        kfree(rt);
1788
1851
        return rc;
1789
1852
}
1790
1853
 
 
1854
static int filename_trans_read(struct policydb *p, void *fp)
 
1855
{
 
1856
        struct filename_trans *ft;
 
1857
        struct filename_trans_datum *otype;
 
1858
        char *name;
 
1859
        u32 nel, len;
 
1860
        __le32 buf[4];
 
1861
        int rc, i;
 
1862
 
 
1863
        if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
 
1864
                return 0;
 
1865
 
 
1866
        rc = next_entry(buf, fp, sizeof(u32));
 
1867
        if (rc)
 
1868
                return rc;
 
1869
        nel = le32_to_cpu(buf[0]);
 
1870
 
 
1871
        for (i = 0; i < nel; i++) {
 
1872
                ft = NULL;
 
1873
                otype = NULL;
 
1874
                name = NULL;
 
1875
 
 
1876
                rc = -ENOMEM;
 
1877
                ft = kzalloc(sizeof(*ft), GFP_KERNEL);
 
1878
                if (!ft)
 
1879
                        goto out;
 
1880
 
 
1881
                rc = -ENOMEM;
 
1882
                otype = kmalloc(sizeof(*otype), GFP_KERNEL);
 
1883
                if (!otype)
 
1884
                        goto out;
 
1885
 
 
1886
                /* length of the path component string */
 
1887
                rc = next_entry(buf, fp, sizeof(u32));
 
1888
                if (rc)
 
1889
                        goto out;
 
1890
                len = le32_to_cpu(buf[0]);
 
1891
 
 
1892
                rc = -ENOMEM;
 
1893
                name = kmalloc(len + 1, GFP_KERNEL);
 
1894
                if (!name)
 
1895
                        goto out;
 
1896
 
 
1897
                ft->name = name;
 
1898
 
 
1899
                /* path component string */
 
1900
                rc = next_entry(name, fp, len);
 
1901
                if (rc)
 
1902
                        goto out;
 
1903
                name[len] = 0;
 
1904
 
 
1905
                rc = next_entry(buf, fp, sizeof(u32) * 4);
 
1906
                if (rc)
 
1907
                        goto out;
 
1908
 
 
1909
                ft->stype = le32_to_cpu(buf[0]);
 
1910
                ft->ttype = le32_to_cpu(buf[1]);
 
1911
                ft->tclass = le32_to_cpu(buf[2]);
 
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);
 
1920
        }
 
1921
        hash_eval(p->filename_trans, "filenametr");
 
1922
        return 0;
 
1923
out:
 
1924
        kfree(ft);
 
1925
        kfree(name);
 
1926
        kfree(otype);
 
1927
 
 
1928
        return rc;
 
1929
}
 
1930
 
1791
1931
static int genfs_read(struct policydb *p, void *fp)
1792
1932
{
1793
1933
        int i, j, rc;
2185
2325
                p->symtab[i].nprim = nprim;
2186
2326
        }
2187
2327
 
 
2328
        rc = -EINVAL;
 
2329
        p->process_class = string_to_security_class(p, "process");
 
2330
        if (!p->process_class)
 
2331
                goto bad;
 
2332
 
2188
2333
        rc = avtab_read(&p->te_avtab, fp, p);
2189
2334
        if (rc)
2190
2335
                goto bad;
2217
2362
                tr->role = le32_to_cpu(buf[0]);
2218
2363
                tr->type = le32_to_cpu(buf[1]);
2219
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
 
2220
2373
                if (!policydb_role_isvalid(p, tr->role) ||
2221
2374
                    !policydb_type_isvalid(p, tr->type) ||
 
2375
                    !policydb_class_isvalid(p, tr->tclass) ||
2222
2376
                    !policydb_role_isvalid(p, tr->new_role))
2223
2377
                        goto bad;
2224
2378
                ltr = tr;
2251
2405
                lra = ra;
2252
2406
        }
2253
2407
 
 
2408
        rc = filename_trans_read(p, fp);
 
2409
        if (rc)
 
2410
                goto bad;
 
2411
 
2254
2412
        rc = policydb_index(p);
2255
2413
        if (rc)
2256
2414
                goto bad;
2257
2415
 
2258
2416
        rc = -EINVAL;
2259
 
        p->process_class = string_to_security_class(p, "process");
2260
 
        if (!p->process_class)
2261
 
                goto bad;
2262
 
 
2263
 
        rc = -EINVAL;
2264
2417
        p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
2265
2418
        p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
2266
2419
        if (!p->process_trans_perms)
2286
2439
                goto bad;
2287
2440
 
2288
2441
        /* preallocate so we don't have to worry about the put ever failing */
2289
 
        rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim - 1,
 
2442
        rc = flex_array_prealloc(p->type_attr_map_array, 0, p->p_types.nprim,
2290
2443
                                 GFP_KERNEL | __GFP_ZERO);
2291
2444
        if (rc)
2292
2445
                goto bad;
2432
2585
        return 0;
2433
2586
}
2434
2587
 
2435
 
static int role_trans_write(struct role_trans *r, void *fp)
 
2588
static int role_trans_write(struct policydb *p, void *fp)
2436
2589
{
 
2590
        struct role_trans *r = p->role_tr;
2437
2591
        struct role_trans *tr;
2438
2592
        u32 buf[3];
2439
2593
        size_t nel;
2453
2607
                rc = put_entry(buf, sizeof(u32), 3, fp);
2454
2608
                if (rc)
2455
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
                }
2456
2616
        }
2457
2617
 
2458
2618
        return 0;
2960
3120
        return 0;
2961
3121
}
2962
3122
 
2963
 
static int range_count(void *key, void *data, void *ptr)
 
3123
static int hashtab_cnt(void *key, void *data, void *ptr)
2964
3124
{
2965
3125
        int *cnt = ptr;
2966
3126
        *cnt = *cnt + 1;
3008
3168
 
3009
3169
        /* count the number of entries in the hashtab */
3010
3170
        nel = 0;
3011
 
        rc = hashtab_map(p->range_tr, range_count, &nel);
 
3171
        rc = hashtab_map(p->range_tr, hashtab_cnt, &nel);
3012
3172
        if (rc)
3013
3173
                return rc;
3014
3174
 
3025
3185
        return 0;
3026
3186
}
3027
3187
 
 
3188
static int filename_write_helper(void *key, void *data, void *ptr)
 
3189
{
 
3190
        __le32 buf[4];
 
3191
        struct filename_trans *ft = key;
 
3192
        struct filename_trans_datum *otype = data;
 
3193
        void *fp = ptr;
 
3194
        int rc;
 
3195
        u32 len;
 
3196
 
 
3197
        len = strlen(ft->name);
 
3198
        buf[0] = cpu_to_le32(len);
 
3199
        rc = put_entry(buf, sizeof(u32), 1, fp);
 
3200
        if (rc)
 
3201
                return rc;
 
3202
 
 
3203
        rc = put_entry(ft->name, sizeof(char), len, fp);
 
3204
        if (rc)
 
3205
                return rc;
 
3206
 
 
3207
        buf[0] = ft->stype;
 
3208
        buf[1] = ft->ttype;
 
3209
        buf[2] = ft->tclass;
 
3210
        buf[3] = otype->otype;
 
3211
 
 
3212
        rc = put_entry(buf, sizeof(u32), 4, fp);
 
3213
        if (rc)
 
3214
                return rc;
 
3215
 
 
3216
        return 0;
 
3217
}
 
3218
 
 
3219
static int filename_trans_write(struct policydb *p, void *fp)
 
3220
{
 
3221
        u32 nel;
 
3222
        __le32 buf[1];
 
3223
        int rc;
 
3224
 
 
3225
        if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)
 
3226
                return 0;
 
3227
 
 
3228
        nel = 0;
 
3229
        rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel);
 
3230
        if (rc)
 
3231
                return rc;
 
3232
 
 
3233
        buf[0] = cpu_to_le32(nel);
 
3234
        rc = put_entry(buf, sizeof(u32), 1, fp);
 
3235
        if (rc)
 
3236
                return rc;
 
3237
 
 
3238
        rc = hashtab_map(p->filename_trans, filename_write_helper, fp);
 
3239
        if (rc)
 
3240
                return rc;
 
3241
 
 
3242
        return 0;
 
3243
}
 
3244
 
3028
3245
/*
3029
3246
 * Write the configuration data in a policy database
3030
3247
 * structure to a policy database binary representation
3127
3344
        if (rc)
3128
3345
                return rc;
3129
3346
 
3130
 
        rc = role_trans_write(p->role_tr, fp);
 
3347
        rc = role_trans_write(p, fp);
3131
3348
        if (rc)
3132
3349
                return rc;
3133
3350
 
3135
3352
        if (rc)
3136
3353
                return rc;
3137
3354
 
 
3355
        rc = filename_trans_write(p, fp);
 
3356
        if (rc)
 
3357
                return rc;
 
3358
 
3138
3359
        rc = ocontext_write(p, info, fp);
3139
3360
        if (rc)
3140
3361
                return rc;