add missing match.c match.h files

This commit is contained in:
John Johansen 2007-02-06 01:19:58 +00:00
parent 9e137352dc
commit f03d370034

View file

@ -3874,3 +3874,367 @@ Index: linux-2.6.19.1/security/apparmor/apparmorfs.c
#define SECFS_AA "apparmor"
static struct dentry *aafs_dentry = NULL;
Index: linux-2.6.19.1/security/apparmor/match.c
===================================================================
--- /dev/null
+++ linux-2.6.19.1/security/apparmor/match.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2002-2005 Novell/SUSE
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * http://forge.novell.com/modules/xfmod/project/?apparmor
+ *
+ * AppArmor aamatch submodule (w/ pattern expansion).
+ *
+ */
+
+#include <asm/unaligned.h>
+#include <linux/module.h>
+#include "match.h"
+
+static const char *features="pattern=aadfa";
+
+static struct table_header *unpack_table(void *blob, size_t bsize)
+{
+ struct table_header *table = NULL;
+ struct table_header th;
+ size_t tsize;
+
+ if (bsize < sizeof(struct table_header))
+ goto out;
+
+ th.td_id = ntohs(get_unaligned((u16 *) (blob)));
+ th.td_flags = ntohs(get_unaligned((u16 *) (blob + 2)));
+ th.td_lolen = ntohl(get_unaligned((u32 *) (blob + 8)));
+ blob += sizeof(struct table_header);
+
+ if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
+ th.td_flags == YYTD_DATA8))
+ goto out;
+
+ tsize = table_size(th.td_lolen, th.td_flags);
+ if (bsize < tsize)
+ goto out;
+
+ table = kmalloc(tsize, GFP_KERNEL);
+ if (table) {
+ *table = th;
+ if (th.td_flags == YYTD_DATA8)
+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+ u8, ntohb);
+ else if (th.td_flags == YYTD_DATA16)
+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+ u16, ntohs);
+ else
+ UNPACK_ARRAY(table->td_data, blob, th.td_lolen,
+ u32, ntohl);
+ }
+
+out:
+ return table;
+}
+
+int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size)
+{
+ int i;
+ int error = -ENOMEM;
+
+ /* get dfa table set header */
+ if (size < sizeof(struct table_set_header))
+ goto fail;
+
+ dfa->th.th_magic = ntohl(get_unaligned((u32 *) (blob + 0)));
+ dfa->th.th_hsize = ntohl(get_unaligned((u32 *) (blob + 4)));
+ dfa->th.th_ssize = ntohl(get_unaligned((u32 *) (blob + 8)));
+ dfa->th.th_flags = ntohs(get_unaligned((u16 *) (blob + 12)));
+
+ if (dfa->th.th_magic != YYTH_MAGIC)
+ goto fail;
+
+ if (size < dfa->th.th_hsize)
+ goto fail;
+
+ blob += dfa->th.th_hsize;
+ size -= dfa->th.th_hsize;
+
+ while (size > 0) {
+ struct table_header *table;
+ table = unpack_table(blob, size);
+ if (!table)
+ goto fail;
+
+ switch(table->td_id) {
+ case YYTD_ID_ACCEPT:
+ case YYTD_ID_BASE:
+ dfa->tables[table->td_id - 1] = table;
+ if (table->td_flags != YYTD_DATA32)
+ goto fail_proto;
+ break;
+ case YYTD_ID_DEF:
+ case YYTD_ID_NXT:
+ case YYTD_ID_CHK:
+ dfa->tables[table->td_id - 1] = table;
+ if (table->td_flags != YYTD_DATA16)
+ goto fail_proto;
+ break;
+ case YYTD_ID_EC:
+ dfa->tables[table->td_id - 1] = table;
+ if (table->td_flags != YYTD_DATA8)
+ goto fail_proto;
+ break;
+ default:
+ kfree(table);
+ goto fail_proto;
+ }
+
+ blob += table_size(table->td_lolen, table->td_flags);
+ size -= table_size(table->td_lolen, table->td_flags);
+ }
+
+ error = 0;
+
+ return error;
+
+fail_proto:
+ error = -EPROTO;
+fail:
+ for (i = 0; i < YYTD_ID_NXT; i++) {
+ if (dfa->tables[i]) {
+ kfree(dfa->tables[i]);
+ dfa->tables[i] = NULL;
+ }
+ }
+ return error;
+}
+
+/**
+ * verify_dfa - verify that all the transitions and states in the dfa tables
+ * are in bounds.
+ * @dfa: dfa to test
+ *
+ * assumes dfa has gone through the verification done by unpacking
+ */
+int verify_dfa(struct aa_dfa *dfa)
+{
+ size_t i, state_count, trans_count;
+ int error = -EPROTO;
+
+ /* check that required tables exist */
+ if (!(dfa->tables[YYTD_ID_ACCEPT -1 ] &&
+ dfa->tables[YYTD_ID_DEF - 1] &&
+ dfa->tables[YYTD_ID_BASE - 1] &&
+ dfa->tables[YYTD_ID_NXT - 1] &&
+ dfa->tables[YYTD_ID_CHK - 1]))
+ goto out;
+
+ /* accept.size == default.size == base.size */
+ state_count = dfa->tables[YYTD_ID_BASE - 1]->td_lolen;
+ if (!(state_count == dfa->tables[YYTD_ID_DEF - 1]->td_lolen &&
+ state_count == dfa->tables[YYTD_ID_ACCEPT - 1]->td_lolen))
+ goto out;
+
+ /* next.size == chk.size */
+ trans_count = dfa->tables[YYTD_ID_NXT - 1]->td_lolen;
+ if (trans_count != dfa->tables[YYTD_ID_CHK - 1]->td_lolen)
+ goto out;
+
+ /* if equivalence classes then its table must be 256 */
+ if (dfa->tables[YYTD_ID_EC - 1] &&
+ dfa->tables[YYTD_ID_EC - 1]->td_lolen != 256)
+ goto out;
+
+ for (i = 0; i < state_count; i++) {
+ if (DEFAULT_TABLE(dfa)[i] >= state_count)
+ goto out;
+ if (BASE_TABLE(dfa)[i] >= trans_count + 256)
+ goto out;
+ }
+
+ for (i = 0; i < trans_count ; i++) {
+ if (NEXT_TABLE(dfa)[i] >= state_count)
+ goto out;
+ if (CHECK_TABLE(dfa)[i] >= state_count)
+ goto out;
+ }
+
+ error = 0;
+out:
+ return error;
+}
+
+struct aa_dfa *aamatch_alloc(void)
+{
+ return kzalloc(sizeof(struct aa_dfa), GFP_KERNEL);
+}
+
+void aamatch_free(struct aa_dfa *dfa)
+{
+ if (dfa) {
+ int i;
+ for (i = 0; i < YYTD_ID_NXT; i++) {
+ kfree(dfa->tables[i]);
+ }
+ }
+ kfree(dfa);
+}
+
+const char *aamatch_features(void)
+{
+ return features;
+}
+
+/**
+ * aadfa_label - return the permissions associated with @state
+ * @dfa: dfa to get state permission from
+ * @state: state in the dfa for which to get a label
+ *
+ * Assumes that state is a valid state of the dfa
+ *
+ * Returns the label associated with @state. 0 indicates the state
+ * is no-accepting/provides no permissions.
+ */
+inline unsigned int aadfa_label(struct aa_dfa *dfa, int state)
+{
+ return ACCEPT_TABLE(dfa)[state];
+}
+
+/**
+ * aadfa_match - match @path against @dfa starting in @state
+ * @dfa: the dfa to match @path against
+ * @state: the state to start matching in
+ * @path: the path to match against the dfa
+ *
+ * aadfa_match will match the full path length and return the state it
+ * finished matching in. The final state returned can be used to
+ * lookup the accepting label or as a starting point to continue matching
+ * with a new string if the path has been broken into multiple components.
+ */
+inline unsigned int aadfa_match(struct aa_dfa *dfa, unsigned int state,
+ const char *path)
+{
+ u8 *s = (u8 *) path;
+ u16 *def = DEFAULT_TABLE(dfa);
+ u32 *base = BASE_TABLE(dfa);
+ u16 *next = NEXT_TABLE(dfa);
+ u16 *check = CHECK_TABLE(dfa);
+ unsigned int pos;
+
+ /* current state is <state>, matching character *s */
+ if (dfa->tables[YYTD_ID_EC - 1]) {
+ u8 *equiv = EQUIV_TABLE(dfa);
+ for ( ; *s; ++s) {
+ pos = base[state] + equiv[*s];
+ if (check[pos] == state)
+ state = next[pos];
+ else
+ state = def[state];
+ }
+ } else {
+ for ( ; *s; ++s) {
+ pos = base[state] + *s;
+ if (check[pos] == state)
+ state = next[pos];
+ else
+ state = def[state];
+ }
+ }
+ return state;
+}
+
+unsigned int aamatch(struct aa_dfa *dfa, const char *pathname)
+{
+ if (dfa)
+ return aadfa_label(dfa, aadfa_match(dfa, 1, pathname));
+
+ return 0;
+}
Index: linux-2.6.19.1/security/apparmor/match.h
===================================================================
--- /dev/null
+++ linux-2.6.19.1/security/apparmor/match.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2002-2005 Novell/SUSE
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2 of the
+ * License.
+ *
+ * AppArmor submodule (match) prototypes
+ */
+
+#ifndef __MATCH_H
+#define __MATCH_H
+
+#define YYTH_MAGIC 0x1B5E783D
+
+struct table_set_header {
+ u32 th_magic; /* TH_MAGIC */
+ u32 th_hsize;
+ u32 th_ssize;
+ u16 th_flags;
+ char th_version[];
+};
+
+#define YYTD_ID_ACCEPT 1 /* 1 */
+#define YYTD_ID_BASE 2 /* 2 */
+#define YYTD_ID_CHK 3 /* 3 */
+#define YYTD_ID_DEF 4 /* 4 */
+#define YYTD_ID_EC 5 /* 5 */
+#define YYTD_ID_NXT 6 /* 8 */
+#define YYTD_ID_META 7 /* 6 */
+
+#define YYTD_DATA8 1
+#define YYTD_DATA16 2
+#define YYTD_DATA32 4
+
+struct table_header {
+ u16 td_id;
+ u16 td_flags;
+ u32 td_hilen;
+ u32 td_lolen;
+ char td_data[];
+};
+
+#define DEFAULT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_DEF - 1]->td_data))
+#define BASE_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_BASE - 1]->td_data))
+#define NEXT_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_NXT - 1]->td_data))
+#define CHECK_TABLE(DFA) ((u16 *)((DFA)->tables[YYTD_ID_CHK - 1]->td_data))
+#define EQUIV_TABLE(DFA) ((u8 *)((DFA)->tables[YYTD_ID_EC - 1]->td_data))
+#define ACCEPT_TABLE(DFA) ((u32 *)((DFA)->tables[YYTD_ID_ACCEPT - 1]->td_data))
+
+struct aa_dfa {
+ struct table_header *tables[YYTD_ID_NXT];
+
+ struct table_set_header th;
+};
+
+#define ntohb(X) (X)
+
+#define UNPACK_ARRAY(TABLE, BLOB, LEN, TYPE, NTOHX) \
+ do { \
+ typeof(LEN) __i; \
+ TYPE *__t = (TYPE *) TABLE; \
+ TYPE *__b = (TYPE *) BLOB; \
+ for (__i = 0; __i < LEN; __i++) { \
+ __t[__i] = NTOHX(__b[__i]); \
+ } \
+ } while (0)
+
+static inline size_t pad64(size_t i)
+{
+ return (i + (size_t)7) & ~(size_t)7;
+}
+
+static inline size_t table_size(size_t len, size_t el_size)
+{
+ return pad64(sizeof(struct table_header) + len * el_size);
+}
+
+#endif /* __MATCH_H */