Changeset 4813

Show
Ignore:
Timestamp:
09/30/08 15:37:59 (2 months ago)
Author:
jmowery
Message:

merged fixes to optional handling and symbol merging from devel branch

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libqpol/src/policy.c

    r4809 r4813  
    4646#include <sepol/module.h> 
    4747#include <sepol/policydb/module.h> 
     48#include <sepol/policydb/avrule_block.h> 
    4849 
    4950#include <stdbool.h> 
     
    471472} 
    472473 
     474/** State tracking struct used in the functions check_disabled, remove_symbol, and prune_disabled_symbols to handle disabled symbols */ 
     475struct symbol_pruning_state 
     476{ 
     477        qpol_policy_t *p; /**< The policy */ 
     478        int symbol_type; /**< The current symbol type being processed */ 
     479}; 
     480 
     481/** Apply callback for hashtab_map_remove_on_error. 
     482 *  This function tests whether a symbol referenced by the policy is declared or only ever required. 
     483 *  Symbols without a declaration are disabled and must be removed. 
     484 *  @param key Symbol key to check. 
     485 *  @param datum Symbol datum to check. 
     486 *  @param args State object (of type struct symbol_pruning_state) 
     487 *  @return 0 if symbol is enabled, 1 if not enabled. 
     488 */ 
     489static int check_disabled(hashtab_key_t key, hashtab_datum_t datum, void *args) 
     490{ 
     491        struct symbol_pruning_state *s = args; 
     492        if (!is_id_enabled((char *)key, &(s->p->p->p), s->symbol_type)) 
     493                return 1; 
     494        return 0; 
     495} 
     496 
     497/** Remove callback for hashtab_map_remove_on_error. 
     498 *  Frees all memory associated with a disabled symbol that has been removed from the symbol table. 
     499 *  @param key Symbol key to remove 
     500 *  @param datum Symbol datum to remove 
     501 *  @param args State object (of type struct symbol_pruning_state) 
     502 *  @post All memory associated with the symbol is freed. 
     503 */ 
     504static void remove_symbol(hashtab_key_t key, hashtab_datum_t datum, void *args) 
     505{ 
     506        struct symbol_pruning_state *s = args; 
     507        switch (s->symbol_type) { 
     508        case SYM_ROLES: 
     509        { 
     510                role_datum_destroy((role_datum_t *) datum); 
     511                break; 
     512        } 
     513        case SYM_TYPES: 
     514        { 
     515                type_datum_destroy((type_datum_t *) datum); 
     516                break; 
     517        } 
     518        case SYM_USERS: 
     519        { 
     520                user_datum_destroy((user_datum_t *) datum); 
     521                break; 
     522        } 
     523        case SYM_BOOLS: 
     524        { 
     525                /* no-op */ 
     526                break; 
     527        } 
     528        case SYM_LEVELS: 
     529        { 
     530                level_datum_destroy((level_datum_t *) datum); 
     531                break; 
     532        } 
     533        case SYM_CATS: 
     534        { 
     535                cat_datum_destroy((cat_datum_t *) datum); 
     536                break; 
     537        } 
     538        default: 
     539                return;                /* invalid type of datum to free; do nothing */ 
     540        } 
     541        free(key); 
     542        free(datum); 
     543} 
     544 
     545/** Remove symbols that are only required but never declared from the policy. 
     546 *  Removes each disabled symbol freeing all memory associated with it. 
     547 *  @param policy The policy from which disabled symbols should be removed. 
     548 *  @return always 0. 
     549 *  @note Since hashtab_map_remove_on_error does not return any error status, 
     550 *  it is impossible to tell if it has failed; if it fails, the policy will 
     551 *  be in an inconsistent state. 
     552 */ 
     553static int prune_disabled_symbols(qpol_policy_t * policy) 
     554{ 
     555        if (policy->type == QPOL_POLICY_KERNEL_BINARY) 
     556                return 0;              /* checkpolicy already prunes disabled symbols */ 
     557        struct symbol_pruning_state state; 
     558        state.p = policy; 
     559        for (state.symbol_type = SYM_ROLES; state.symbol_type < SYM_NUM; state.symbol_type++) { 
     560                hashtab_map_remove_on_error(policy->p->p.symtab[state.symbol_type].table, check_disabled, remove_symbol, &state); 
     561        } 
     562        return 0; 
     563} 
     564 
     565/** For all symbols that are multiply defined (such as attributes, roles, and users), 
     566 *  union the relevant sets of types and roles from each declaration. 
     567 *  @param policy The policy containig the symbols to union. 
     568 *  @return 0 on success, non-zero on error; if the call fails, 
     569 *  errno will be set, and the policy should be considered invalid. 
     570 */ 
     571static int union_multiply_declared_symbols(qpol_policy_t * policy) { 
     572        /* general structure of this function: 
     573        walk role and user symbol tables for each role/user/attribute 
     574                get datum from symtab, get key from array 
     575                look up symbol in scope table 
     576                foreach decl_id in scope entry 
     577                        union types/roles bitmap with datum's copy 
     578        */ 
     579        qpol_iterator_t * iter = NULL; 
     580        int error = 0; 
     581        if (qpol_policy_get_type_iter(policy, &iter)) { 
     582                return 1; 
     583        } 
     584        for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { 
     585                type_datum_t *attr; 
     586                if (qpol_iterator_get_item(iter, (void**)&attr)) { 
     587                        error = errno; 
     588                        goto err; 
     589                } 
     590                unsigned char isattr = 0; 
     591                if (qpol_type_get_isattr(policy, attr, &isattr)) { 
     592                        error = errno; 
     593                        goto err; 
     594                } 
     595                if (!isattr) 
     596                        continue; 
     597                const char *name; 
     598                if (qpol_type_get_name(policy, (qpol_type_t*)attr, &name)) { 
     599                        error = errno; 
     600                        goto err; 
     601                } 
     602                policydb_t *db = &policy->p->p; 
     603                avrule_block_t *blk = db->global; 
     604                for (; blk; blk = blk->next) { 
     605                        avrule_decl_t *decl = blk->enabled; 
     606                        if (!decl) 
     607                                continue; /* disabled */ 
     608                        type_datum_t *internal_datum = hashtab_search(decl->symtab[SYM_TYPES].table, (const hashtab_key_t)name); 
     609                        if (internal_datum == NULL) { 
     610                                continue; /* not declared here */ 
     611                        } 
     612                        if (ebitmap_union(&attr->types, &internal_datum->types)) 
     613                        { 
     614                                error = errno; 
     615                                ERR(policy, "could not merge declarations for attribute %s", name); 
     616                                goto err; 
     617                        } 
     618                } 
     619        } 
     620        qpol_iterator_destroy(&iter); 
     621 
     622        /* repeat for roles */ 
     623        if (qpol_policy_get_role_iter(policy, &iter)) { 
     624                return 1; 
     625        } 
     626        for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { 
     627                role_datum_t *role; 
     628                if (qpol_iterator_get_item(iter, (void**)&role)) { 
     629                        error = errno; 
     630                        goto err; 
     631                } 
     632                const char *name; 
     633                if (qpol_role_get_name(policy, (qpol_role_t*)role, &name)) { 
     634                        error = errno; 
     635                        goto err; 
     636                } 
     637                policydb_t *db = &policy->p->p; 
     638                scope_datum_t* scope_datum = hashtab_search(db->scope[SYM_ROLES].table, (const hashtab_key_t)name); 
     639                if (scope_datum == NULL) { 
     640                        ERR(policy, "could not find scope datum for role %s", name); 
     641                        error = ENOENT; 
     642                        goto err; 
     643                } 
     644                for (uint32_t i = 0; i < scope_datum->decl_ids_len; i++) 
     645                { 
     646                        if (db->decl_val_to_struct[scope_datum->decl_ids[i] - 1]->enabled == 0) 
     647                                continue; /* block is disabled */ 
     648                        role_datum_t *internal_datum = hashtab_search(db->decl_val_to_struct[scope_datum->decl_ids[i] - 1]->symtab[SYM_ROLES].table, (const hashtab_key_t)name); 
     649                        if (internal_datum == NULL) { 
     650                                continue; /* not declared here */ 
     651                        } 
     652                        if (ebitmap_union(&role->types.types, &internal_datum->types.types) || ebitmap_union(&role->dominates, &internal_datum->dominates)) 
     653                        { 
     654                                error = errno; 
     655                                ERR(policy, "could not merge declarations for role %s", name); 
     656                                goto err; 
     657                        } 
     658                } 
     659        } 
     660        qpol_iterator_destroy(&iter); 
     661 
     662        /* repeat for users */ 
     663        if (qpol_policy_get_user_iter(policy, &iter)) { 
     664                return 1; 
     665        } 
     666        for (; !qpol_iterator_end(iter); qpol_iterator_next(iter)) { 
     667                user_datum_t *user; 
     668                if (qpol_iterator_get_item(iter, (void**)&user)) { 
     669                        error = errno; 
     670                        goto err; 
     671                } 
     672                const char *name; 
     673                if (qpol_user_get_name(policy, (qpol_user_t*)user, &name)) { 
     674                        error = errno; 
     675                        goto err; 
     676                } 
     677                policydb_t *db = &policy->p->p; 
     678                scope_datum_t* scope_datum = hashtab_search(db->scope[SYM_USERS].table, (const hashtab_key_t)name); 
     679                if (scope_datum == NULL) { 
     680                        ERR(policy, "could not find scope datum for user %s", name); 
     681                        error = ENOENT; 
     682                        goto err; 
     683                } 
     684                for (uint32_t i = 0; i < scope_datum->decl_ids_len; i++) 
     685                { 
     686                        if (db->decl_val_to_struct[scope_datum->decl_ids[i] - 1]->enabled == 0) 
     687                                continue; /* block is disabled */ 
     688                        user_datum_t *internal_datum = hashtab_search(db->decl_val_to_struct[scope_datum->decl_ids[i] -1 ]->symtab[SYM_USERS].table, (const hashtab_key_t)name); 
     689                        if (internal_datum == NULL) { 
     690                                continue; /* not declared here */ 
     691                        } 
     692                        if (ebitmap_union(&user->roles.roles, &internal_datum->roles.roles)) 
     693                        { 
     694                                error = errno; 
     695                                ERR(policy, "could not merge declarations for user %s", name); 
     696                                goto err; 
     697                        } 
     698                } 
     699        } 
     700        qpol_iterator_destroy(&iter); 
     701 
     702        return 0; 
     703err: 
     704        qpol_iterator_destroy(&iter); 
     705        errno = error; 
     706        return 1; 
     707} 
     708 
    473709/* forward declarations see policy_extend.c */ 
    474710struct qpol_extended_image; 
     
    584820        } 
    585821 
     822        if (prune_disabled_symbols(policy)) { 
     823                error = errno; 
     824                goto err; 
     825        } 
     826 
     827        if (union_multiply_declared_symbols(policy)) { 
     828                error = errno; 
     829                goto err; 
     830        } 
     831 
    586832        if (qpol_expand_module(policy, !(policy->options & (QPOL_POLICY_OPTION_NO_NEVERALLOWS)))) { 
    587833                error = errno; 
     
    7931039                avtab_init(&((*policy)->p->p.te_avtab)); 
    7941040                avtab_init(&((*policy)->p->p.te_cond_avtab)); 
     1041 
     1042                if (prune_disabled_symbols(*policy)) { 
     1043                        error = errno; 
     1044                        goto err; 
     1045                } 
     1046 
     1047                if (union_multiply_declared_symbols(*policy)) { 
     1048                        error = errno; 
     1049                        goto err; 
     1050                } 
    7951051 
    7961052                /* expand */ 
     
    9121168        avtab_init(&((*policy)->p->p.te_cond_avtab)); 
    9131169 
    914         /* expand :) */ 
     1170        if (prune_disabled_symbols(*policy)) { 
     1171                error = errno; 
     1172                goto err; 
     1173        } 
     1174 
     1175        if (union_multiply_declared_symbols(*policy)) { 
     1176                error = errno; 
     1177                goto err; 
     1178        } 
     1179 
     1180        /* expand */ 
    9151181        if (qpol_expand_module(*policy, !(options & (QPOL_POLICY_OPTION_NO_NEVERALLOWS)))) { 
    9161182                error = errno; 
  • trunk/libqpol/src/policy_define.c

    r4806 r4813  
    5858#include <sepol/policydb/polcaps.h> 
    5959#endif 
     60#include <sepol/errcodes.h> 
    6061 
    6162#include "queue.h" 
  • trunk/libqpol/src/policy_extend.c

    r4778 r4813  
    3333#include <sepol/policydb/ebitmap.h> 
    3434#include <sepol/policydb/expand.h> 
     35#include <sepol/errcodes.h> 
    3536#include <qpol/policy.h> 
    3637#include <qpol/policy_extend.h>