linux/security/apparmor/include/match.h
<<
>>
Prefs
   1/*
   2 * AppArmor security module
   3 *
   4 * This file contains AppArmor policy dfa matching engine definitions.
   5 *
   6 * Copyright (C) 1998-2008 Novell/SUSE
   7 * Copyright 2009-2012 Canonical Ltd.
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 * modify it under the terms of the GNU General Public License as
  11 * published by the Free Software Foundation, version 2 of the
  12 * License.
  13 */
  14
  15#ifndef __AA_MATCH_H
  16#define __AA_MATCH_H
  17
  18#include <linux/kref.h>
  19
  20#define DFA_NOMATCH                     0
  21#define DFA_START                       1
  22
  23
  24/**
  25 * The format used for transition tables is based on the GNU flex table
  26 * file format (--tables-file option; see Table File Format in the flex
  27 * info pages and the flex sources for documentation). The magic number
  28 * used in the header is 0x1B5E783D instead of 0xF13C57B1 though, because
  29 * new tables have been defined and others YY_ID_CHK (check) and YY_ID_DEF
  30 * (default) tables are used slightly differently (see the apparmor-parser
  31 * package).
  32 *
  33 *
  34 * The data in the packed dfa is stored in network byte order, and the tables
  35 * are arranged for flexibility.  We convert the table data to host native
  36 * byte order.
  37 *
  38 * The dfa begins with a table set header, and is followed by the actual
  39 * tables.
  40 */
  41
  42#define YYTH_MAGIC      0x1B5E783D
  43#define YYTH_FLAG_DIFF_ENCODE   1
  44
  45struct table_set_header {
  46        u32 th_magic;           /* YYTH_MAGIC */
  47        u32 th_hsize;
  48        u32 th_ssize;
  49        u16 th_flags;
  50        char th_version[];
  51};
  52
  53/* The YYTD_ID are one less than flex table mappings.  The flex id
  54 * has 1 subtracted at table load time, this allows us to directly use the
  55 * ID's as indexes.
  56 */
  57#define YYTD_ID_ACCEPT  0
  58#define YYTD_ID_BASE    1
  59#define YYTD_ID_CHK     2
  60#define YYTD_ID_DEF     3
  61#define YYTD_ID_EC      4
  62#define YYTD_ID_META    5
  63#define YYTD_ID_ACCEPT2 6
  64#define YYTD_ID_NXT     7
  65#define YYTD_ID_TSIZE   8
  66#define YYTD_ID_MAX     8
  67
  68#define YYTD_DATA8      1
  69#define YYTD_DATA16     2
  70#define YYTD_DATA32     4
  71#define YYTD_DATA64     8
  72
  73/* ACCEPT & ACCEPT2 tables gets 6 dedicated flags, YYTD_DATAX define the
  74 * first flags
  75 */
  76#define ACCEPT1_FLAGS(X) ((X) & 0x3f)
  77#define ACCEPT2_FLAGS(X) ACCEPT1_FLAGS((X) >> YYTD_ID_ACCEPT2)
  78#define TO_ACCEPT1_FLAG(X) ACCEPT1_FLAGS(X)
  79#define TO_ACCEPT2_FLAG(X) (ACCEPT1_FLAGS(X) << YYTD_ID_ACCEPT2)
  80#define DFA_FLAG_VERIFY_STATES 0x1000
  81
  82struct table_header {
  83        u16 td_id;
  84        u16 td_flags;
  85        u32 td_hilen;
  86        u32 td_lolen;
  87        char td_data[];
  88};
  89
  90#define DEFAULT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_DEF]->td_data))
  91#define BASE_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_BASE]->td_data))
  92#define NEXT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_NXT]->td_data))
  93#define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK]->td_data))
  94#define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC]->td_data))
  95#define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT]->td_data))
  96#define ACCEPT_TABLE2(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT2]->td_data))
  97
  98struct aa_dfa {
  99        struct kref count;
 100        u16 flags;
 101        struct table_header *tables[YYTD_ID_TSIZE];
 102};
 103
 104extern struct aa_dfa *nulldfa;
 105extern struct aa_dfa *stacksplitdfa;
 106
 107#define byte_to_byte(X) (X)
 108
 109#define UNPACK_ARRAY(TABLE, BLOB, LEN, TTYPE, BTYPE, NTOHX)     \
 110        do { \
 111                typeof(LEN) __i; \
 112                TTYPE *__t = (TTYPE *) TABLE; \
 113                BTYPE *__b = (BTYPE *) BLOB; \
 114                for (__i = 0; __i < LEN; __i++) { \
 115                        __t[__i] = NTOHX(__b[__i]); \
 116                } \
 117        } while (0)
 118
 119static inline size_t table_size(size_t len, size_t el_size)
 120{
 121        return ALIGN(sizeof(struct table_header) + len * el_size, 8);
 122}
 123
 124int aa_setup_dfa_engine(void);
 125void aa_teardown_dfa_engine(void);
 126
 127struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags);
 128unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start,
 129                              const char *str, int len);
 130unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start,
 131                          const char *str);
 132unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state,
 133                         const char c);
 134unsigned int aa_dfa_match_until(struct aa_dfa *dfa, unsigned int start,
 135                                const char *str, const char **retpos);
 136unsigned int aa_dfa_matchn_until(struct aa_dfa *dfa, unsigned int start,
 137                                 const char *str, int n, const char **retpos);
 138
 139void aa_dfa_free_kref(struct kref *kref);
 140
 141#define WB_HISTORY_SIZE 8
 142struct match_workbuf {
 143        unsigned int count;
 144        unsigned int pos;
 145        unsigned int len;
 146        unsigned int size;      /* power of 2, same as history size */
 147        unsigned int history[WB_HISTORY_SIZE];
 148};
 149#define DEFINE_MATCH_WB(N)              \
 150struct match_workbuf N = {              \
 151        .count = 0,                     \
 152        .pos = 0,                       \
 153        .len = 0,                       \
 154        .size = WB_HISTORY_SIZE,                        \
 155}
 156
 157unsigned int aa_dfa_leftmatch(struct aa_dfa *dfa, unsigned int start,
 158                              const char *str, unsigned int *count);
 159
 160/**
 161 * aa_get_dfa - increment refcount on dfa @p
 162 * @dfa: dfa  (MAYBE NULL)
 163 *
 164 * Returns: pointer to @dfa if @dfa is NULL will return NULL
 165 * Requires: @dfa must be held with valid refcount when called
 166 */
 167static inline struct aa_dfa *aa_get_dfa(struct aa_dfa *dfa)
 168{
 169        if (dfa)
 170                kref_get(&(dfa->count));
 171
 172        return dfa;
 173}
 174
 175/**
 176 * aa_put_dfa - put a dfa refcount
 177 * @dfa: dfa to put refcount   (MAYBE NULL)
 178 *
 179 * Requires: if @dfa != NULL that a valid refcount be held
 180 */
 181static inline void aa_put_dfa(struct aa_dfa *dfa)
 182{
 183        if (dfa)
 184                kref_put(&dfa->count, aa_dfa_free_kref);
 185}
 186
 187#define MATCH_FLAG_DIFF_ENCODE 0x80000000
 188#define MARK_DIFF_ENCODE 0x40000000
 189
 190#endif /* __AA_MATCH_H */
 191