mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-04 08:24:42 +01:00
add missing match.c match.h files
This commit is contained in:
parent
9e137352dc
commit
f03d370034
1 changed files with 364 additions and 0 deletions
|
@ -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 */
|
||||
|
|
Loading…
Add table
Reference in a new issue