mirror of
https://gitlab.com/apparmor/apparmor.git
synced 2025-03-06 09:21:00 +01:00

- rework how null transitions are done. M fix-profile-namespaces.diff - fix namespaces to use the :namespace: syntax A cap-set.diff - allow a profile to set a tasks capabilities similar to fscap A rlimits.diff - allow control of a tasks rlimits
134 lines
4.3 KiB
Diff
134 lines
4.3 KiB
Diff
---
|
|
security/apparmor/match.c | 74 +++++++++++++++++++++++++++++++---------------
|
|
1 file changed, 51 insertions(+), 23 deletions(-)
|
|
|
|
--- a/security/apparmor/match.c
|
|
+++ b/security/apparmor/match.c
|
|
@@ -213,17 +213,23 @@ void aa_match_free(struct aa_dfa *dfa)
|
|
}
|
|
|
|
/**
|
|
- * aa_dfa_next_state - traverse @dfa to find state @str stops at
|
|
+ * aa_dfa_next_state_len - traverse @dfa to find state @str stops at
|
|
* @dfa: the dfa to match @str against
|
|
* @start: the state of the dfa to start matching in
|
|
- * @str: the string to match against the dfa
|
|
+ * @str: the string of bytes to match against the dfa
|
|
+ * @len: length of the string of bytes to match
|
|
*
|
|
* aa_dfa_next_state 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.
|
|
+ *
|
|
+ * aa_dfa_next_state could be implement using this function by doing
|
|
+ * return aa_dfa_next_state_len(dfa, start, str, strlen(str));
|
|
+ * but that would require traversing the string twice and be slightly
|
|
+ * slower.
|
|
*/
|
|
-unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start,
|
|
- const char *str)
|
|
+unsigned int aa_dfa_next_state_len(struct aa_dfa *dfa, unsigned int start,
|
|
+ const char *str, int len)
|
|
{
|
|
u16 *def = DEFAULT_TABLE(dfa);
|
|
u32 *base = BASE_TABLE(dfa);
|
|
@@ -237,7 +243,7 @@ unsigned int aa_dfa_next_state(struct aa
|
|
/* current state is <state>, matching character *str */
|
|
if (dfa->tables[YYTD_ID_EC - 1]) {
|
|
u8 *equiv = EQUIV_TABLE(dfa);
|
|
- while (*str) {
|
|
+ for (; len; len--) {
|
|
pos = base[state] + equiv[(u8)*str++];
|
|
if (check[pos] == state)
|
|
state = next[pos];
|
|
@@ -245,7 +251,7 @@ unsigned int aa_dfa_next_state(struct aa
|
|
state = def[state];
|
|
}
|
|
} else {
|
|
- while (*str) {
|
|
+ for (; len; len--) {
|
|
pos = base[state] + (u8)*str++;
|
|
if (check[pos] == state)
|
|
state = next[pos];
|
|
@@ -257,15 +263,17 @@ unsigned int aa_dfa_next_state(struct aa
|
|
}
|
|
|
|
/**
|
|
- * aa_dfa_null_transition - step to next state after null character
|
|
- * @dfa: the dfa to match against
|
|
+ * aa_dfa_next_state - traverse @dfa to find state @str stops at
|
|
+ * @dfa: the dfa to match @str against
|
|
* @start: the state of the dfa to start matching in
|
|
+ * @str: the null terminated string of bytes to match against the dfa
|
|
*
|
|
- * aa_dfa_null_transition transitions to the next state after a null
|
|
- * character which is not used in standard matching and is only
|
|
- * used to seperate pairs.
|
|
+ * aa_dfa_next_state 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.
|
|
*/
|
|
-unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start)
|
|
+unsigned int aa_dfa_next_state(struct aa_dfa *dfa, unsigned int start,
|
|
+ const char *str)
|
|
{
|
|
u16 *def = DEFAULT_TABLE(dfa);
|
|
u32 *base = BASE_TABLE(dfa);
|
|
@@ -273,26 +281,46 @@ unsigned int aa_dfa_null_transition(stru
|
|
u16 *check = CHECK_TABLE(dfa);
|
|
unsigned int state = start, pos;
|
|
|
|
+ if (state == 0)
|
|
+ return 0;
|
|
+
|
|
/* current state is <state>, matching character *str */
|
|
if (dfa->tables[YYTD_ID_EC - 1]) {
|
|
u8 *equiv = EQUIV_TABLE(dfa);
|
|
- pos = base[state] + equiv[0];
|
|
- if (check[pos] == state)
|
|
- state = next[pos];
|
|
- else
|
|
- state = def[state];
|
|
+ while (*str) {
|
|
+ pos = base[state] + equiv[(u8)*str++];
|
|
+ if (check[pos] == state)
|
|
+ state = next[pos];
|
|
+ else
|
|
+ state = def[state];
|
|
+ }
|
|
} else {
|
|
- pos = base[state] + 0;
|
|
- if (check[pos] == state)
|
|
- state = next[pos];
|
|
- else
|
|
- state = def[state];
|
|
+ while (*str) {
|
|
+ pos = base[state] + (u8)*str++;
|
|
+ if (check[pos] == state)
|
|
+ state = next[pos];
|
|
+ else
|
|
+ state = def[state];
|
|
+ }
|
|
}
|
|
-
|
|
return state;
|
|
}
|
|
|
|
/**
|
|
+ * aa_dfa_null_transition - step to next state after null character
|
|
+ * @dfa: the dfa to match against
|
|
+ * @start: the state of the dfa to start matching in
|
|
+ *
|
|
+ * aa_dfa_null_transition transitions to the next state after a null
|
|
+ * character which is not used in standard matching and is only
|
|
+ * used to seperate pairs.
|
|
+ */
|
|
+unsigned int aa_dfa_null_transition(struct aa_dfa *dfa, unsigned int start)
|
|
+{
|
|
+ return aa_dfa_next_state_len(dfa, start, "", 1);
|
|
+}
|
|
+
|
|
+/**
|
|
* aa_dfa_match - find accept perm for @str in @dfa
|
|
* @dfa: the dfa to match @str against
|
|
* @str: the string to match against the dfa
|