hackedteam/core-android-native

View on GitHub
selinux_native/jni/libsepol/src/booleans.c

Summary

Maintainability
Test Coverage
#include <string.h>
#include <stdlib.h>

#include "handle.h"
#include "private.h"
#include "debug.h"
#include "log.h"

#include <sepol/booleans.h>
#include <sepol/policydb/hashtab.h>
#include <sepol/policydb/policydb.h>
#include <sepol/policydb/conditional.h>
#include "boolean_internal.h"

static int bool_update(sepol_handle_t * handle,
               policydb_t * policydb,
               const sepol_bool_key_t * key, const sepol_bool_t * data)
{

    const char *cname;
    char *name;
    int value;

    sepol_bool_key_unpack(key, &cname);
    name = strdup(cname);
    value = sepol_bool_get_value(data);

    if (!name)
        goto omem;

    cond_bool_datum_t *datum =
        hashtab_search(policydb->p_bools.table, name);
    if (!datum) {
        LOGD("boolean %s no longer in policy", name);
        goto err;
    }
    if (value != 0 && value != 1) {
        LOGD("illegal value %d for boolean %s", value, name);
        goto err;
    }

    free(name);
    datum->state = value;
    return STATUS_SUCCESS;

      omem:
    LOGD("out of memory");

      err:
    free(name);
    LOGD("could not update boolean %s", cname);
    return STATUS_ERR;
}

static int bool_to_record(sepol_handle_t * handle,
              const policydb_t * policydb,
              int bool_idx, sepol_bool_t ** record)
{

    const char *name = policydb->p_bool_val_to_name[bool_idx];
    cond_bool_datum_t *booldatum = policydb->bool_val_to_struct[bool_idx];
    int value = booldatum->state;

    sepol_bool_t *tmp_record = NULL;

    if (sepol_bool_create(handle, &tmp_record) < 0)
        goto err;

    if (sepol_bool_set_name(handle, tmp_record, name) < 0)
        goto err;

    sepol_bool_set_value(tmp_record, value);

    *record = tmp_record;
    return STATUS_SUCCESS;

      err:
    LOGD("could not convert boolean %s to record", name);
    sepol_bool_free(tmp_record);
    return STATUS_ERR;
}

int sepol_bool_set(sepol_handle_t * handle,
           sepol_policydb_t * p,
           const sepol_bool_key_t * key, const sepol_bool_t * data)
{

    const char *name;
    sepol_bool_key_unpack(key, &name);

    policydb_t *policydb = &p->p;
    if (bool_update(handle, policydb, key, data) < 0)
        goto err;

    if (evaluate_conds(policydb) < 0) {
        LOGD("error while re-evaluating conditionals");
        goto err;
    }

    return STATUS_SUCCESS;

      err:
    LOGD("could not set boolean %s", name);
    return STATUS_ERR;
}

int sepol_bool_count(sepol_handle_t * handle __attribute__ ((unused)),
             const sepol_policydb_t * p, unsigned int *response)
{

    const policydb_t *policydb = &p->p;
    *response = policydb->p_bools.nprim;

    handle = NULL;
    return STATUS_SUCCESS;
}

int sepol_bool_exists(sepol_handle_t * handle,
              const sepol_policydb_t * p,
              const sepol_bool_key_t * key, int *response)
{

    const policydb_t *policydb = &p->p;

    const char *cname;
    char *name = NULL;
    sepol_bool_key_unpack(key, &cname);
    name = strdup(cname);

    if (!name) {
        LOGD("out of memory, could not check "
            "if user %s exists", cname);
        return STATUS_ERR;
    }

    *response = (hashtab_search(policydb->p_bools.table, name) != NULL);
    free(name);
    return STATUS_SUCCESS;
}

int sepol_bool_query(sepol_handle_t * handle,
             const sepol_policydb_t * p,
             const sepol_bool_key_t * key, sepol_bool_t ** response)
{

    const policydb_t *policydb = &p->p;
    cond_bool_datum_t *booldatum = NULL;

    const char *cname;
    char *name = NULL;
    sepol_bool_key_unpack(key, &cname);
    name = strdup(cname);

    if (!name)
        goto omem;

    booldatum = hashtab_search(policydb->p_bools.table, name);
    if (!booldatum) {
        *response = NULL;
        return STATUS_SUCCESS;
    }

    if (bool_to_record(handle, policydb,
               booldatum->s.value - 1, response) < 0)
        goto err;

    free(name);
    return STATUS_SUCCESS;

      omem:
    LOGD("out of memory");

      err:
    LOGD("could not query boolean %s", cname);
    free(name);
    return STATUS_ERR;
}

int sepol_bool_iterate(sepol_handle_t * handle,
               const sepol_policydb_t * p,
               int (*fn) (const sepol_bool_t * boolean,
                  void *fn_arg), void *arg)
{

    const policydb_t *policydb = &p->p;
    unsigned int nbools = policydb->p_bools.nprim;
    sepol_bool_t *boolean = NULL;
    unsigned int i;

    /* For each boolean */
    for (i = 0; i < nbools; i++) {

        int status;

        if (bool_to_record(handle, policydb, i, &boolean) < 0)
            goto err;

        /* Invoke handler */
        status = fn(boolean, arg);
        if (status < 0)
            goto err;

        sepol_bool_free(boolean);
        boolean = NULL;

        /* Handler requested exit */
        if (status > 0)
            break;
    }

    return STATUS_SUCCESS;

      err:
    LOGD("could not iterate over booleans");
    sepol_bool_free(boolean);
    return STATUS_ERR;
}