From f3b7bdd5d5f034bd49a1cdd0c38567efeb8b8bcc Mon Sep 17 00:00:00 2001 From: John Johansen Date: Thu, 16 Feb 2012 06:20:26 -0800 Subject: [PATCH] --- yaml --- r: 292303 b: refs/heads/master c: 0fe1212d0539eb6c1e27d388711172d786e299cc h: refs/heads/master i: 292301: f9611ac6a9758f42826a708561dcbfde7d7d3e38 292299: 5372bc3d6467f9c9f9e77d31a1be0599fa396c18 292295: 09d444f04355eab35a237c9b5da65b90f007b169 292287: a9cc0ae647f0d597d42df6e51493db671f869890 v: v3 --- [refs] | 2 +- trunk/security/apparmor/include/apparmor.h | 2 +- trunk/security/apparmor/include/match.h | 3 + trunk/security/apparmor/match.c | 80 +++++++++++++++++++++- 4 files changed, 82 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index ed86020c2ef1..ea81004d8182 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3372b68a3c982611dcc30b3c872f8bbdee019e5e +refs/heads/master: 0fe1212d0539eb6c1e27d388711172d786e299cc diff --git a/trunk/security/apparmor/include/apparmor.h b/trunk/security/apparmor/include/apparmor.h index df3649560818..248c408ddc1b 100644 --- a/trunk/security/apparmor/include/apparmor.h +++ b/trunk/security/apparmor/include/apparmor.h @@ -81,7 +81,7 @@ static inline unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start) { /* the null transition only needs the string's null terminator byte */ - return aa_dfa_match_len(dfa, start, "", 1); + return aa_dfa_next(dfa, start, 0); } static inline bool mediated_filesystem(struct inode *inode) diff --git a/trunk/security/apparmor/include/match.h b/trunk/security/apparmor/include/match.h index a4a863997bd5..775843e7f984 100644 --- a/trunk/security/apparmor/include/match.h +++ b/trunk/security/apparmor/include/match.h @@ -116,6 +116,9 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start, const char *str, int len); unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start, const char *str); +unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, + const char c); + void aa_dfa_free_kref(struct kref *kref); /** diff --git a/trunk/security/apparmor/match.c b/trunk/security/apparmor/match.c index 94de6b4907c8..90971a8c3789 100644 --- a/trunk/security/apparmor/match.c +++ b/trunk/security/apparmor/match.c @@ -335,12 +335,12 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start, } /** - * aa_dfa_next_state - traverse @dfa to find state @str stops at + * aa_dfa_match - traverse @dfa to find state @str stops at * @dfa: the dfa to match @str against (NOT NULL) * @start: the state of the dfa to start matching in * @str: the null terminated string of bytes to match against the dfa (NOT NULL) * - * aa_dfa_next_state will match @str against the dfa and return the state it + * aa_dfa_match will match @str against the dfa and return the state it * finished matching in. The final state can be used to look up the accepting * label, or as the start state of a continuing match. * @@ -349,5 +349,79 @@ unsigned int aa_dfa_match_len(struct aa_dfa *dfa, unsigned int start, unsigned int aa_dfa_match(struct aa_dfa *dfa, unsigned int start, const char *str) { - return aa_dfa_match_len(dfa, start, str, strlen(str)); + u16 *def = DEFAULT_TABLE(dfa); + u32 *base = BASE_TABLE(dfa); + u16 *next = NEXT_TABLE(dfa); + u16 *check = CHECK_TABLE(dfa); + unsigned int state = start, pos; + + if (state == 0) + return 0; + + /* current state is , matching character *str */ + if (dfa->tables[YYTD_ID_EC]) { + /* Equivalence class table defined */ + u8 *equiv = EQUIV_TABLE(dfa); + /* default is direct to next state */ + while (*str) { + pos = base[state] + equiv[(u8) *str++]; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } + } else { + /* default is direct to next state */ + while (*str) { + pos = base[state] + (u8) *str++; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } + } + + return state; +} + +/** + * aa_dfa_next - step one character to the next state in the dfa + * @dfa: the dfa to tranverse (NOT NULL) + * @state: the state to start in + * @c: the input character to transition on + * + * aa_dfa_match will step through the dfa by one input character @c + * + * Returns: state reach after input @c + */ +unsigned int aa_dfa_next(struct aa_dfa *dfa, unsigned int state, + const char c) +{ + 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 , matching character *str */ + if (dfa->tables[YYTD_ID_EC]) { + /* Equivalence class table defined */ + u8 *equiv = EQUIV_TABLE(dfa); + /* default is direct to next state */ + + pos = base[state] + equiv[(u8) c]; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } else { + /* default is direct to next state */ + pos = base[state] + (u8) c; + if (check[pos] == state) + state = next[pos]; + else + state = def[state]; + } + + return state; }