aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/policydb.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/policydb.c')
-rw-r--r--security/selinux/ss/policydb.c841
1 files changed, 841 insertions, 0 deletions
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 97fb0cf0eb69..94f630d93a5c 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -37,6 +37,7 @@
37#include "policydb.h" 37#include "policydb.h"
38#include "conditional.h" 38#include "conditional.h"
39#include "mls.h" 39#include "mls.h"
40#include "services.h"
40 41
41#define _DEBUG_HASHES 42#define _DEBUG_HASHES
42 43
@@ -2316,3 +2317,843 @@ bad:
2316 policydb_destroy(p); 2317 policydb_destroy(p);
2317 goto out; 2318 goto out;
2318} 2319}
2320
2321/*
2322 * Write a MLS level structure to a policydb binary
2323 * representation file.
2324 */
2325static int mls_write_level(struct mls_level *l, void *fp)
2326{
2327 __le32 buf[1];
2328 int rc;
2329
2330 buf[0] = cpu_to_le32(l->sens);
2331 rc = put_entry(buf, sizeof(u32), 1, fp);
2332 if (rc)
2333 return rc;
2334
2335 rc = ebitmap_write(&l->cat, fp);
2336 if (rc)
2337 return rc;
2338
2339 return 0;
2340}
2341
2342/*
2343 * Write a MLS range structure to a policydb binary
2344 * representation file.
2345 */
2346static int mls_write_range_helper(struct mls_range *r, void *fp)
2347{
2348 __le32 buf[3];
2349 size_t items;
2350 int rc, eq;
2351
2352 eq = mls_level_eq(&r->level[1], &r->level[0]);
2353
2354 if (eq)
2355 items = 2;
2356 else
2357 items = 3;
2358 buf[0] = cpu_to_le32(items-1);
2359 buf[1] = cpu_to_le32(r->level[0].sens);
2360 if (!eq)
2361 buf[2] = cpu_to_le32(r->level[1].sens);
2362
2363 BUG_ON(items > (sizeof(buf)/sizeof(buf[0])));
2364
2365 rc = put_entry(buf, sizeof(u32), items, fp);
2366 if (rc)
2367 return rc;
2368
2369 rc = ebitmap_write(&r->level[0].cat, fp);
2370 if (rc)
2371 return rc;
2372 if (!eq) {
2373 rc = ebitmap_write(&r->level[1].cat, fp);
2374 if (rc)
2375 return rc;
2376 }
2377
2378 return 0;
2379}
2380
2381static int sens_write(void *vkey, void *datum, void *ptr)
2382{
2383 char *key = vkey;
2384 struct level_datum *levdatum = datum;
2385 struct policy_data *pd = ptr;
2386 void *fp = pd->fp;
2387 __le32 buf[2];
2388 size_t len;
2389 int rc;
2390
2391 len = strlen(key);
2392 buf[0] = cpu_to_le32(len);
2393 buf[1] = cpu_to_le32(levdatum->isalias);
2394 rc = put_entry(buf, sizeof(u32), 2, fp);
2395 if (rc)
2396 return rc;
2397
2398 rc = put_entry(key, 1, len, fp);
2399 if (rc)
2400 return rc;
2401
2402 rc = mls_write_level(levdatum->level, fp);
2403 if (rc)
2404 return rc;
2405
2406 return 0;
2407}
2408
2409static int cat_write(void *vkey, void *datum, void *ptr)
2410{
2411 char *key = vkey;
2412 struct cat_datum *catdatum = datum;
2413 struct policy_data *pd = ptr;
2414 void *fp = pd->fp;
2415 __le32 buf[3];
2416 size_t len;
2417 int rc;
2418
2419 len = strlen(key);
2420 buf[0] = cpu_to_le32(len);
2421 buf[1] = cpu_to_le32(catdatum->value);
2422 buf[2] = cpu_to_le32(catdatum->isalias);
2423 rc = put_entry(buf, sizeof(u32), 3, fp);
2424 if (rc)
2425 return rc;
2426
2427 rc = put_entry(key, 1, len, fp);
2428 if (rc)
2429 return rc;
2430
2431 return 0;
2432}
2433
2434static int role_trans_write(struct role_trans *r, void *fp)
2435{
2436 struct role_trans *tr;
2437 u32 buf[3];
2438 size_t nel;
2439 int rc;
2440
2441 nel = 0;
2442 for (tr = r; tr; tr = tr->next)
2443 nel++;
2444 buf[0] = cpu_to_le32(nel);
2445 rc = put_entry(buf, sizeof(u32), 1, fp);
2446 if (rc)
2447 return rc;
2448 for (tr = r; tr; tr = tr->next) {
2449 buf[0] = cpu_to_le32(tr->role);
2450 buf[1] = cpu_to_le32(tr->type);
2451 buf[2] = cpu_to_le32(tr->new_role);
2452 rc = put_entry(buf, sizeof(u32), 3, fp);
2453 if (rc)
2454 return rc;
2455 }
2456
2457 return 0;
2458}
2459
2460static int role_allow_write(struct role_allow *r, void *fp)
2461{
2462 struct role_allow *ra;
2463 u32 buf[2];
2464 size_t nel;
2465 int rc;
2466
2467 nel = 0;
2468 for (ra = r; ra; ra = ra->next)
2469 nel++;
2470 buf[0] = cpu_to_le32(nel);
2471 rc = put_entry(buf, sizeof(u32), 1, fp);
2472 if (rc)
2473 return rc;
2474 for (ra = r; ra; ra = ra->next) {
2475 buf[0] = cpu_to_le32(ra->role);
2476 buf[1] = cpu_to_le32(ra->new_role);
2477 rc = put_entry(buf, sizeof(u32), 2, fp);
2478 if (rc)
2479 return rc;
2480 }
2481 return 0;
2482}
2483
2484/*
2485 * Write a security context structure
2486 * to a policydb binary representation file.
2487 */
2488static int context_write(struct policydb *p, struct context *c,
2489 void *fp)
2490{
2491 int rc;
2492 __le32 buf[3];
2493
2494 buf[0] = cpu_to_le32(c->user);
2495 buf[1] = cpu_to_le32(c->role);
2496 buf[2] = cpu_to_le32(c->type);
2497
2498 rc = put_entry(buf, sizeof(u32), 3, fp);
2499 if (rc)
2500 return rc;
2501
2502 rc = mls_write_range_helper(&c->range, fp);
2503 if (rc)
2504 return rc;
2505
2506 return 0;
2507}
2508
2509/*
2510 * The following *_write functions are used to
2511 * write the symbol data to a policy database
2512 * binary representation file.
2513 */
2514
2515static int perm_write(void *vkey, void *datum, void *fp)
2516{
2517 char *key = vkey;
2518 struct perm_datum *perdatum = datum;
2519 __le32 buf[2];
2520 size_t len;
2521 int rc;
2522
2523 len = strlen(key);
2524 buf[0] = cpu_to_le32(len);
2525 buf[1] = cpu_to_le32(perdatum->value);
2526 rc = put_entry(buf, sizeof(u32), 2, fp);
2527 if (rc)
2528 return rc;
2529
2530 rc = put_entry(key, 1, len, fp);
2531 if (rc)
2532 return rc;
2533
2534 return 0;
2535}
2536
2537static int common_write(void *vkey, void *datum, void *ptr)
2538{
2539 char *key = vkey;
2540 struct common_datum *comdatum = datum;
2541 struct policy_data *pd = ptr;
2542 void *fp = pd->fp;
2543 __le32 buf[4];
2544 size_t len;
2545 int rc;
2546
2547 len = strlen(key);
2548 buf[0] = cpu_to_le32(len);
2549 buf[1] = cpu_to_le32(comdatum->value);
2550 buf[2] = cpu_to_le32(comdatum->permissions.nprim);
2551 buf[3] = cpu_to_le32(comdatum->permissions.table->nel);
2552 rc = put_entry(buf, sizeof(u32), 4, fp);
2553 if (rc)
2554 return rc;
2555
2556 rc = put_entry(key, 1, len, fp);
2557 if (rc)
2558 return rc;
2559
2560 rc = hashtab_map(comdatum->permissions.table, perm_write, fp);
2561 if (rc)
2562 return rc;
2563
2564 return 0;
2565}
2566
2567static int write_cons_helper(struct policydb *p, struct constraint_node *node,
2568 void *fp)
2569{
2570 struct constraint_node *c;
2571 struct constraint_expr *e;
2572 __le32 buf[3];
2573 u32 nel;
2574 int rc;
2575
2576 for (c = node; c; c = c->next) {
2577 nel = 0;
2578 for (e = c->expr; e; e = e->next)
2579 nel++;
2580 buf[0] = cpu_to_le32(c->permissions);
2581 buf[1] = cpu_to_le32(nel);
2582 rc = put_entry(buf, sizeof(u32), 2, fp);
2583 if (rc)
2584 return rc;
2585 for (e = c->expr; e; e = e->next) {
2586 buf[0] = cpu_to_le32(e->expr_type);
2587 buf[1] = cpu_to_le32(e->attr);
2588 buf[2] = cpu_to_le32(e->op);
2589 rc = put_entry(buf, sizeof(u32), 3, fp);
2590 if (rc)
2591 return rc;
2592
2593 switch (e->expr_type) {
2594 case CEXPR_NAMES:
2595 rc = ebitmap_write(&e->names, fp);
2596 if (rc)
2597 return rc;
2598 break;
2599 default:
2600 break;
2601 }
2602 }
2603 }
2604
2605 return 0;
2606}
2607
2608static int class_write(void *vkey, void *datum, void *ptr)
2609{
2610 char *key = vkey;
2611 struct class_datum *cladatum = datum;
2612 struct policy_data *pd = ptr;
2613 void *fp = pd->fp;
2614 struct policydb *p = pd->p;
2615 struct constraint_node *c;
2616 __le32 buf[6];
2617 u32 ncons;
2618 size_t len, len2;
2619 int rc;
2620
2621 len = strlen(key);
2622 if (cladatum->comkey)
2623 len2 = strlen(cladatum->comkey);
2624 else
2625 len2 = 0;
2626
2627 ncons = 0;
2628 for (c = cladatum->constraints; c; c = c->next)
2629 ncons++;
2630
2631 buf[0] = cpu_to_le32(len);
2632 buf[1] = cpu_to_le32(len2);
2633 buf[2] = cpu_to_le32(cladatum->value);
2634 buf[3] = cpu_to_le32(cladatum->permissions.nprim);
2635 if (cladatum->permissions.table)
2636 buf[4] = cpu_to_le32(cladatum->permissions.table->nel);
2637 else
2638 buf[4] = 0;
2639 buf[5] = cpu_to_le32(ncons);
2640 rc = put_entry(buf, sizeof(u32), 6, fp);
2641 if (rc)
2642 return rc;
2643
2644 rc = put_entry(key, 1, len, fp);
2645 if (rc)
2646 return rc;
2647
2648 if (cladatum->comkey) {
2649 rc = put_entry(cladatum->comkey, 1, len2, fp);
2650 if (rc)
2651 return rc;
2652 }
2653
2654 rc = hashtab_map(cladatum->permissions.table, perm_write, fp);
2655 if (rc)
2656 return rc;
2657
2658 rc = write_cons_helper(p, cladatum->constraints, fp);
2659 if (rc)
2660 return rc;
2661
2662 /* write out the validatetrans rule */
2663 ncons = 0;
2664 for (c = cladatum->validatetrans; c; c = c->next)
2665 ncons++;
2666
2667 buf[0] = cpu_to_le32(ncons);
2668 rc = put_entry(buf, sizeof(u32), 1, fp);
2669 if (rc)
2670 return rc;
2671
2672 rc = write_cons_helper(p, cladatum->validatetrans, fp);
2673 if (rc)
2674 return rc;
2675
2676 return 0;
2677}
2678
2679static int role_write(void *vkey, void *datum, void *ptr)
2680{
2681 char *key = vkey;
2682 struct role_datum *role = datum;
2683 struct policy_data *pd = ptr;
2684 void *fp = pd->fp;
2685 struct policydb *p = pd->p;
2686 __le32 buf[3];
2687 size_t items, len;
2688 int rc;
2689
2690 len = strlen(key);
2691 items = 0;
2692 buf[items++] = cpu_to_le32(len);
2693 buf[items++] = cpu_to_le32(role->value);
2694 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
2695 buf[items++] = cpu_to_le32(role->bounds);
2696
2697 BUG_ON(items > (sizeof(buf)/sizeof(buf[0])));
2698
2699 rc = put_entry(buf, sizeof(u32), items, fp);
2700 if (rc)
2701 return rc;
2702
2703 rc = put_entry(key, 1, len, fp);
2704 if (rc)
2705 return rc;
2706
2707 rc = ebitmap_write(&role->dominates, fp);
2708 if (rc)
2709 return rc;
2710
2711 rc = ebitmap_write(&role->types, fp);
2712 if (rc)
2713 return rc;
2714
2715 return 0;
2716}
2717
2718static int type_write(void *vkey, void *datum, void *ptr)
2719{
2720 char *key = vkey;
2721 struct type_datum *typdatum = datum;
2722 struct policy_data *pd = ptr;
2723 struct policydb *p = pd->p;
2724 void *fp = pd->fp;
2725 __le32 buf[4];
2726 int rc;
2727 size_t items, len;
2728
2729 len = strlen(key);
2730 items = 0;
2731 buf[items++] = cpu_to_le32(len);
2732 buf[items++] = cpu_to_le32(typdatum->value);
2733 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) {
2734 u32 properties = 0;
2735
2736 if (typdatum->primary)
2737 properties |= TYPEDATUM_PROPERTY_PRIMARY;
2738
2739 if (typdatum->attribute)
2740 properties |= TYPEDATUM_PROPERTY_ATTRIBUTE;
2741
2742 buf[items++] = cpu_to_le32(properties);
2743 buf[items++] = cpu_to_le32(typdatum->bounds);
2744 } else {
2745 buf[items++] = cpu_to_le32(typdatum->primary);
2746 }
2747 BUG_ON(items > (sizeof(buf) / sizeof(buf[0])));
2748 rc = put_entry(buf, sizeof(u32), items, fp);
2749 if (rc)
2750 return rc;
2751
2752 rc = put_entry(key, 1, len, fp);
2753 if (rc)
2754 return rc;
2755
2756 return 0;
2757}
2758
2759static int user_write(void *vkey, void *datum, void *ptr)
2760{
2761 char *key = vkey;
2762 struct user_datum *usrdatum = datum;
2763 struct policy_data *pd = ptr;
2764 struct policydb *p = pd->p;
2765 void *fp = pd->fp;
2766 __le32 buf[3];
2767 size_t items, len;
2768 int rc;
2769
2770 len = strlen(key);
2771 items = 0;
2772 buf[items++] = cpu_to_le32(len);
2773 buf[items++] = cpu_to_le32(usrdatum->value);
2774 if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
2775 buf[items++] = cpu_to_le32(usrdatum->bounds);
2776 BUG_ON(items > (sizeof(buf) / sizeof(buf[0])));
2777 rc = put_entry(buf, sizeof(u32), items, fp);
2778 if (rc)
2779 return rc;
2780
2781 rc = put_entry(key, 1, len, fp);
2782 if (rc)
2783 return rc;
2784
2785 rc = ebitmap_write(&usrdatum->roles, fp);
2786 if (rc)
2787 return rc;
2788
2789 rc = mls_write_range_helper(&usrdatum->range, fp);
2790 if (rc)
2791 return rc;
2792
2793 rc = mls_write_level(&usrdatum->dfltlevel, fp);
2794 if (rc)
2795 return rc;
2796
2797 return 0;
2798}
2799
2800static int (*write_f[SYM_NUM]) (void *key, void *datum,
2801 void *datap) =
2802{
2803 common_write,
2804 class_write,
2805 role_write,
2806 type_write,
2807 user_write,
2808 cond_write_bool,
2809 sens_write,
2810 cat_write,
2811};
2812
2813static int ocontext_write(struct policydb *p, struct policydb_compat_info *info,
2814 void *fp)
2815{
2816 unsigned int i, j, rc;
2817 size_t nel, len;
2818 __le32 buf[3];
2819 u32 nodebuf[8];
2820 struct ocontext *c;
2821 for (i = 0; i < info->ocon_num; i++) {
2822 nel = 0;
2823 for (c = p->ocontexts[i]; c; c = c->next)
2824 nel++;
2825 buf[0] = cpu_to_le32(nel);
2826 rc = put_entry(buf, sizeof(u32), 1, fp);
2827 if (rc)
2828 return rc;
2829 for (c = p->ocontexts[i]; c; c = c->next) {
2830 switch (i) {
2831 case OCON_ISID:
2832 buf[0] = cpu_to_le32(c->sid[0]);
2833 rc = put_entry(buf, sizeof(u32), 1, fp);
2834 if (rc)
2835 return rc;
2836 rc = context_write(p, &c->context[0], fp);
2837 if (rc)
2838 return rc;
2839 break;
2840 case OCON_FS:
2841 case OCON_NETIF:
2842 len = strlen(c->u.name);
2843 buf[0] = cpu_to_le32(len);
2844 rc = put_entry(buf, sizeof(u32), 1, fp);
2845 if (rc)
2846 return rc;
2847 rc = put_entry(c->u.name, 1, len, fp);
2848 if (rc)
2849 return rc;
2850 rc = context_write(p, &c->context[0], fp);
2851 if (rc)
2852 return rc;
2853 rc = context_write(p, &c->context[1], fp);
2854 if (rc)
2855 return rc;
2856 break;
2857 case OCON_PORT:
2858 buf[0] = cpu_to_le32(c->u.port.protocol);
2859 buf[1] = cpu_to_le32(c->u.port.low_port);
2860 buf[2] = cpu_to_le32(c->u.port.high_port);
2861 rc = put_entry(buf, sizeof(u32), 3, fp);
2862 if (rc)
2863 return rc;
2864 rc = context_write(p, &c->context[0], fp);
2865 if (rc)
2866 return rc;
2867 break;
2868 case OCON_NODE:
2869 nodebuf[0] = c->u.node.addr; /* network order */
2870 nodebuf[1] = c->u.node.mask; /* network order */
2871 rc = put_entry(nodebuf, sizeof(u32), 2, fp);
2872 if (rc)
2873 return rc;
2874 rc = context_write(p, &c->context[0], fp);
2875 if (rc)
2876 return rc;
2877 break;
2878 case OCON_FSUSE:
2879 buf[0] = cpu_to_le32(c->v.behavior);
2880 len = strlen(c->u.name);
2881 buf[1] = cpu_to_le32(len);
2882 rc = put_entry(buf, sizeof(u32), 2, fp);
2883 if (rc)
2884 return rc;
2885 rc = put_entry(c->u.name, 1, len, fp);
2886 if (rc)
2887 return rc;
2888 rc = context_write(p, &c->context[0], fp);
2889 if (rc)
2890 return rc;
2891 break;
2892 case OCON_NODE6:
2893 for (j = 0; j < 4; j++)
2894 nodebuf[j] = c->u.node6.addr[j]; /* network order */
2895 for (j = 0; j < 4; j++)
2896 nodebuf[j + 4] = c->u.node6.mask[j]; /* network order */
2897 rc = put_entry(nodebuf, sizeof(u32), 8, fp);
2898 if (rc)
2899 return rc;
2900 rc = context_write(p, &c->context[0], fp);
2901 if (rc)
2902 return rc;
2903 break;
2904 }
2905 }
2906 }
2907 return 0;
2908}
2909
2910static int genfs_write(struct policydb *p, void *fp)
2911{
2912 struct genfs *genfs;
2913 struct ocontext *c;
2914 size_t len;
2915 __le32 buf[1];
2916 int rc;
2917
2918 len = 0;
2919 for (genfs = p->genfs; genfs; genfs = genfs->next)
2920 len++;
2921 buf[0] = cpu_to_le32(len);
2922 rc = put_entry(buf, sizeof(u32), 1, fp);
2923 if (rc)
2924 return rc;
2925 for (genfs = p->genfs; genfs; genfs = genfs->next) {
2926 len = strlen(genfs->fstype);
2927 buf[0] = cpu_to_le32(len);
2928 rc = put_entry(buf, sizeof(u32), 1, fp);
2929 if (rc)
2930 return rc;
2931 rc = put_entry(genfs->fstype, 1, len, fp);
2932 if (rc)
2933 return rc;
2934 len = 0;
2935 for (c = genfs->head; c; c = c->next)
2936 len++;
2937 buf[0] = cpu_to_le32(len);
2938 rc = put_entry(buf, sizeof(u32), 1, fp);
2939 if (rc)
2940 return rc;
2941 for (c = genfs->head; c; c = c->next) {
2942 len = strlen(c->u.name);
2943 buf[0] = cpu_to_le32(len);
2944 rc = put_entry(buf, sizeof(u32), 1, fp);
2945 if (rc)
2946 return rc;
2947 rc = put_entry(c->u.name, 1, len, fp);
2948 if (rc)
2949 return rc;
2950 buf[0] = cpu_to_le32(c->v.sclass);
2951 rc = put_entry(buf, sizeof(u32), 1, fp);
2952 if (rc)
2953 return rc;
2954 rc = context_write(p, &c->context[0], fp);
2955 if (rc)
2956 return rc;
2957 }
2958 }
2959 return 0;
2960}
2961
2962static int range_count(void *key, void *data, void *ptr)
2963{
2964 int *cnt = ptr;
2965 *cnt = *cnt + 1;
2966
2967 return 0;
2968}
2969
2970static int range_write_helper(void *key, void *data, void *ptr)
2971{
2972 __le32 buf[2];
2973 struct range_trans *rt = key;
2974 struct mls_range *r = data;
2975 struct policy_data *pd = ptr;
2976 void *fp = pd->fp;
2977 struct policydb *p = pd->p;
2978 int rc;
2979
2980 buf[0] = cpu_to_le32(rt->source_type);
2981 buf[1] = cpu_to_le32(rt->target_type);
2982 rc = put_entry(buf, sizeof(u32), 2, fp);
2983 if (rc)
2984 return rc;
2985 if (p->policyvers >= POLICYDB_VERSION_RANGETRANS) {
2986 buf[0] = cpu_to_le32(rt->target_class);
2987 rc = put_entry(buf, sizeof(u32), 1, fp);
2988 if (rc)
2989 return rc;
2990 }
2991 rc = mls_write_range_helper(r, fp);
2992 if (rc)
2993 return rc;
2994
2995 return 0;
2996}
2997
2998static int range_write(struct policydb *p, void *fp)
2999{
3000 size_t nel;
3001 __le32 buf[1];
3002 int rc;
3003 struct policy_data pd;
3004
3005 pd.p = p;
3006 pd.fp = fp;
3007
3008 /* count the number of entries in the hashtab */
3009 nel = 0;
3010 rc = hashtab_map(p->range_tr, range_count, &nel);
3011 if (rc)
3012 return rc;
3013
3014 buf[0] = cpu_to_le32(nel);
3015 rc = put_entry(buf, sizeof(u32), 1, fp);
3016 if (rc)
3017 return rc;
3018
3019 /* actually write all of the entries */
3020 rc = hashtab_map(p->range_tr, range_write_helper, &pd);
3021 if (rc)
3022 return rc;
3023
3024 return 0;
3025}
3026
3027/*
3028 * Write the configuration data in a policy database
3029 * structure to a policy database binary representation
3030 * file.
3031 */
3032int policydb_write(struct policydb *p, void *fp)
3033{
3034 unsigned int i, num_syms;
3035 int rc;
3036 __le32 buf[4];
3037 u32 config;
3038 size_t len;
3039 struct policydb_compat_info *info;
3040
3041 /*
3042 * refuse to write policy older than compressed avtab
3043 * to simplify the writer. There are other tests dropped
3044 * since we assume this throughout the writer code. Be
3045 * careful if you ever try to remove this restriction
3046 */
3047 if (p->policyvers < POLICYDB_VERSION_AVTAB) {
3048 printk(KERN_ERR "SELinux: refusing to write policy version %d."
3049 " Because it is less than version %d\n", p->policyvers,
3050 POLICYDB_VERSION_AVTAB);
3051 return -EINVAL;
3052 }
3053
3054 config = 0;
3055 if (p->mls_enabled)
3056 config |= POLICYDB_CONFIG_MLS;
3057
3058 if (p->reject_unknown)
3059 config |= REJECT_UNKNOWN;
3060 if (p->allow_unknown)
3061 config |= ALLOW_UNKNOWN;
3062
3063 /* Write the magic number and string identifiers. */
3064 buf[0] = cpu_to_le32(POLICYDB_MAGIC);
3065 len = strlen(POLICYDB_STRING);
3066 buf[1] = cpu_to_le32(len);
3067 rc = put_entry(buf, sizeof(u32), 2, fp);
3068 if (rc)
3069 return rc;
3070 rc = put_entry(POLICYDB_STRING, 1, len, fp);
3071 if (rc)
3072 return rc;
3073
3074 /* Write the version, config, and table sizes. */
3075 info = policydb_lookup_compat(p->policyvers);
3076 if (!info) {
3077 printk(KERN_ERR "SELinux: compatibility lookup failed for policy "
3078 "version %d", p->policyvers);
3079 return rc;
3080 }
3081
3082 buf[0] = cpu_to_le32(p->policyvers);
3083 buf[1] = cpu_to_le32(config);
3084 buf[2] = cpu_to_le32(info->sym_num);
3085 buf[3] = cpu_to_le32(info->ocon_num);
3086
3087 rc = put_entry(buf, sizeof(u32), 4, fp);
3088 if (rc)
3089 return rc;
3090
3091 if (p->policyvers >= POLICYDB_VERSION_POLCAP) {
3092 rc = ebitmap_write(&p->policycaps, fp);
3093 if (rc)
3094 return rc;
3095 }
3096
3097 if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE) {
3098 rc = ebitmap_write(&p->permissive_map, fp);
3099 if (rc)
3100 return rc;
3101 }
3102
3103 num_syms = info->sym_num;
3104 for (i = 0; i < num_syms; i++) {
3105 struct policy_data pd;
3106
3107 pd.fp = fp;
3108 pd.p = p;
3109
3110 buf[0] = cpu_to_le32(p->symtab[i].nprim);
3111 buf[1] = cpu_to_le32(p->symtab[i].table->nel);
3112
3113 rc = put_entry(buf, sizeof(u32), 2, fp);
3114 if (rc)
3115 return rc;
3116 rc = hashtab_map(p->symtab[i].table, write_f[i], &pd);
3117 if (rc)
3118 return rc;
3119 }
3120
3121 rc = avtab_write(p, &p->te_avtab, fp);
3122 if (rc)
3123 return rc;
3124
3125 rc = cond_write_list(p, p->cond_list, fp);
3126 if (rc)
3127 return rc;
3128
3129 rc = role_trans_write(p->role_tr, fp);
3130 if (rc)
3131 return rc;
3132
3133 rc = role_allow_write(p->role_allow, fp);
3134 if (rc)
3135 return rc;
3136
3137 rc = ocontext_write(p, info, fp);
3138 if (rc)
3139 return rc;
3140
3141 rc = genfs_write(p, fp);
3142 if (rc)
3143 return rc;
3144
3145 rc = range_write(p, fp);
3146 if (rc)
3147 return rc;
3148
3149 for (i = 0; i < p->p_types.nprim; i++) {
3150 struct ebitmap *e = flex_array_get(p->type_attr_map_array, i);
3151
3152 BUG_ON(!e);
3153 rc = ebitmap_write(e, fp);
3154 if (rc)
3155 return rc;
3156 }
3157
3158 return 0;
3159}