cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

list.c (7296B)


      1/*
      2 * QEMU access control list authorization driver
      3 *
      4 * Copyright (c) 2018 Red Hat, Inc.
      5 *
      6 * This library is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU Lesser General Public
      8 * License as published by the Free Software Foundation; either
      9 * version 2.1 of the License, or (at your option) any later version.
     10 *
     11 * This library is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     18 *
     19 */
     20
     21#include "qemu/osdep.h"
     22#include "authz/list.h"
     23#include "trace.h"
     24#include "qom/object_interfaces.h"
     25#include "qapi/qapi-visit-authz.h"
     26#include "qemu/module.h"
     27
     28static bool qauthz_list_is_allowed(QAuthZ *authz,
     29                                   const char *identity,
     30                                   Error **errp)
     31{
     32    QAuthZList *lauthz = QAUTHZ_LIST(authz);
     33    QAuthZListRuleList *rules = lauthz->rules;
     34
     35    while (rules) {
     36        QAuthZListRule *rule = rules->value;
     37        QAuthZListFormat format = rule->has_format ? rule->format :
     38            QAUTHZ_LIST_FORMAT_EXACT;
     39
     40        trace_qauthz_list_check_rule(authz, rule->match, identity,
     41                                     format, rule->policy);
     42        switch (format) {
     43        case QAUTHZ_LIST_FORMAT_EXACT:
     44            if (g_str_equal(rule->match, identity)) {
     45                return rule->policy == QAUTHZ_LIST_POLICY_ALLOW;
     46            }
     47            break;
     48        case QAUTHZ_LIST_FORMAT_GLOB:
     49            if (g_pattern_match_simple(rule->match, identity)) {
     50                return rule->policy == QAUTHZ_LIST_POLICY_ALLOW;
     51            }
     52            break;
     53        default:
     54            g_warn_if_reached();
     55            return false;
     56        }
     57        rules = rules->next;
     58    }
     59
     60    trace_qauthz_list_default_policy(authz, identity, lauthz->policy);
     61    return lauthz->policy == QAUTHZ_LIST_POLICY_ALLOW;
     62}
     63
     64
     65static void
     66qauthz_list_prop_set_policy(Object *obj,
     67                            int value,
     68                            Error **errp G_GNUC_UNUSED)
     69{
     70    QAuthZList *lauthz = QAUTHZ_LIST(obj);
     71
     72    lauthz->policy = value;
     73}
     74
     75
     76static int
     77qauthz_list_prop_get_policy(Object *obj,
     78                            Error **errp G_GNUC_UNUSED)
     79{
     80    QAuthZList *lauthz = QAUTHZ_LIST(obj);
     81
     82    return lauthz->policy;
     83}
     84
     85
     86static void
     87qauthz_list_prop_get_rules(Object *obj, Visitor *v, const char *name,
     88                           void *opaque, Error **errp)
     89{
     90    QAuthZList *lauthz = QAUTHZ_LIST(obj);
     91
     92    visit_type_QAuthZListRuleList(v, name, &lauthz->rules, errp);
     93}
     94
     95static void
     96qauthz_list_prop_set_rules(Object *obj, Visitor *v, const char *name,
     97                           void *opaque, Error **errp)
     98{
     99    QAuthZList *lauthz = QAUTHZ_LIST(obj);
    100    QAuthZListRuleList *oldrules;
    101
    102    oldrules = lauthz->rules;
    103    visit_type_QAuthZListRuleList(v, name, &lauthz->rules, errp);
    104
    105    qapi_free_QAuthZListRuleList(oldrules);
    106}
    107
    108
    109static void
    110qauthz_list_finalize(Object *obj)
    111{
    112    QAuthZList *lauthz = QAUTHZ_LIST(obj);
    113
    114    qapi_free_QAuthZListRuleList(lauthz->rules);
    115}
    116
    117
    118static void
    119qauthz_list_class_init(ObjectClass *oc, void *data)
    120{
    121    QAuthZClass *authz = QAUTHZ_CLASS(oc);
    122
    123    object_class_property_add_enum(oc, "policy",
    124                                   "QAuthZListPolicy",
    125                                   &QAuthZListPolicy_lookup,
    126                                   qauthz_list_prop_get_policy,
    127                                   qauthz_list_prop_set_policy);
    128
    129    object_class_property_add(oc, "rules", "QAuthZListRule",
    130                              qauthz_list_prop_get_rules,
    131                              qauthz_list_prop_set_rules,
    132                              NULL, NULL);
    133
    134    authz->is_allowed = qauthz_list_is_allowed;
    135}
    136
    137
    138QAuthZList *qauthz_list_new(const char *id,
    139                            QAuthZListPolicy policy,
    140                            Error **errp)
    141{
    142    return QAUTHZ_LIST(
    143        object_new_with_props(TYPE_QAUTHZ_LIST,
    144                              object_get_objects_root(),
    145                              id, errp,
    146                              "policy", QAuthZListPolicy_str(policy),
    147                              NULL));
    148}
    149
    150ssize_t qauthz_list_append_rule(QAuthZList *auth,
    151                                const char *match,
    152                                QAuthZListPolicy policy,
    153                                QAuthZListFormat format,
    154                                Error **errp)
    155{
    156    QAuthZListRule *rule;
    157    QAuthZListRuleList *rules, *tmp;
    158    size_t i = 0;
    159
    160    rule = g_new0(QAuthZListRule, 1);
    161    rule->policy = policy;
    162    rule->match = g_strdup(match);
    163    rule->format = format;
    164    rule->has_format = true;
    165
    166    tmp = g_new0(QAuthZListRuleList, 1);
    167    tmp->value = rule;
    168
    169    rules = auth->rules;
    170    if (rules) {
    171        while (rules->next) {
    172            i++;
    173            rules = rules->next;
    174        }
    175        rules->next = tmp;
    176        return i + 1;
    177    } else {
    178        auth->rules = tmp;
    179        return 0;
    180    }
    181}
    182
    183
    184ssize_t qauthz_list_insert_rule(QAuthZList *auth,
    185                                const char *match,
    186                                QAuthZListPolicy policy,
    187                                QAuthZListFormat format,
    188                                size_t index,
    189                                Error **errp)
    190{
    191    QAuthZListRule *rule;
    192    QAuthZListRuleList *rules, *tmp;
    193    size_t i = 0;
    194
    195    rule = g_new0(QAuthZListRule, 1);
    196    rule->policy = policy;
    197    rule->match = g_strdup(match);
    198    rule->format = format;
    199    rule->has_format = true;
    200
    201    tmp = g_new0(QAuthZListRuleList, 1);
    202    tmp->value = rule;
    203
    204    rules = auth->rules;
    205    if (rules && index > 0) {
    206        while (rules->next && i < (index - 1)) {
    207            i++;
    208            rules = rules->next;
    209        }
    210        tmp->next = rules->next;
    211        rules->next = tmp;
    212        return i + 1;
    213    } else {
    214        tmp->next = auth->rules;
    215        auth->rules = tmp;
    216        return 0;
    217    }
    218}
    219
    220
    221ssize_t qauthz_list_delete_rule(QAuthZList *auth, const char *match)
    222{
    223    QAuthZListRule *rule;
    224    QAuthZListRuleList *rules, *prev;
    225    size_t i = 0;
    226
    227    prev = NULL;
    228    rules = auth->rules;
    229    while (rules) {
    230        rule = rules->value;
    231        if (g_str_equal(rule->match, match)) {
    232            if (prev) {
    233                prev->next = rules->next;
    234            } else {
    235                auth->rules = rules->next;
    236            }
    237            rules->next = NULL;
    238            qapi_free_QAuthZListRuleList(rules);
    239            return i;
    240        }
    241        prev = rules;
    242        rules = rules->next;
    243        i++;
    244    }
    245
    246    return -1;
    247}
    248
    249
    250static const TypeInfo qauthz_list_info = {
    251    .parent = TYPE_QAUTHZ,
    252    .name = TYPE_QAUTHZ_LIST,
    253    .instance_size = sizeof(QAuthZList),
    254    .instance_finalize = qauthz_list_finalize,
    255    .class_init = qauthz_list_class_init,
    256    .interfaces = (InterfaceInfo[]) {
    257        { TYPE_USER_CREATABLE },
    258        { }
    259    }
    260};
    261
    262
    263static void
    264qauthz_list_register_types(void)
    265{
    266    type_register_static(&qauthz_list_info);
    267}
    268
    269
    270type_init(qauthz_list_register_types);