hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/security/apparmor/match.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * AppArmor security module
34 *
....@@ -5,11 +6,6 @@
56 *
67 * Copyright (C) 1998-2008 Novell/SUSE
78 * 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.
139 */
1410
1511 #include <linux/errno.h>
....@@ -211,6 +207,26 @@
211207 if (!(BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE) &&
212208 (DEFAULT_TABLE(dfa)[i] >= state_count))
213209 goto out;
210
+ if (BASE_TABLE(dfa)[i] & MATCH_FLAGS_INVALID) {
211
+ pr_err("AppArmor DFA state with invalid match flags");
212
+ goto out;
213
+ }
214
+ if ((BASE_TABLE(dfa)[i] & MATCH_FLAG_DIFF_ENCODE)) {
215
+ if (!(dfa->flags & YYTH_FLAG_DIFF_ENCODE)) {
216
+ pr_err("AppArmor DFA diff encoded transition state without header flag");
217
+ goto out;
218
+ }
219
+ }
220
+ if ((BASE_TABLE(dfa)[i] & MATCH_FLAG_OOB_TRANSITION)) {
221
+ if (base_idx(BASE_TABLE(dfa)[i]) < dfa->max_oob) {
222
+ pr_err("AppArmor DFA out of bad transition out of range");
223
+ goto out;
224
+ }
225
+ if (!(dfa->flags & YYTH_FLAG_OOB_TRANS)) {
226
+ pr_err("AppArmor DFA out of bad transition state without header flag");
227
+ goto out;
228
+ }
229
+ }
214230 if (base_idx(BASE_TABLE(dfa)[i]) + 255 >= trans_count) {
215231 pr_err("AppArmor DFA next/check upper bounds error\n");
216232 goto out;
....@@ -313,8 +329,22 @@
313329 goto fail;
314330
315331 dfa->flags = ntohs(*(__be16 *) (data + 12));
316
- if (dfa->flags != 0 && dfa->flags != YYTH_FLAG_DIFF_ENCODE)
332
+ if (dfa->flags & ~(YYTH_FLAGS))
317333 goto fail;
334
+
335
+ /*
336
+ * TODO: needed for dfa to support more than 1 oob
337
+ * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
338
+ * if (hsize < 16 + 4)
339
+ * goto fail;
340
+ * dfa->max_oob = ntol(*(__be32 *) (data + 16));
341
+ * if (dfa->max <= MAX_OOB_SUPPORTED) {
342
+ * pr_err("AppArmor DFA OOB greater than supported\n");
343
+ * goto fail;
344
+ * }
345
+ * }
346
+ */
347
+ dfa->max_oob = 1;
318348
319349 data += hsize;
320350 size -= hsize;
....@@ -504,6 +534,23 @@
504534 return state;
505535 }
506536
537
+unsigned int aa_dfa_outofband_transition(struct aa_dfa *dfa, unsigned int state)
538
+{
539
+ u16 *def = DEFAULT_TABLE(dfa);
540
+ u32 *base = BASE_TABLE(dfa);
541
+ u16 *next = NEXT_TABLE(dfa);
542
+ u16 *check = CHECK_TABLE(dfa);
543
+ u32 b = (base)[(state)];
544
+
545
+ if (!(b & MATCH_FLAG_OOB_TRANSITION))
546
+ return DFA_NOMATCH;
547
+
548
+ /* No Equivalence class remapping for outofband transitions */
549
+ match_char(state, def, base, next, check, -1);
550
+
551
+ return state;
552
+}
553
+
507554 /**
508555 * aa_dfa_match_until - traverse @dfa until accept state or end of input
509556 * @dfa: the dfa to match @str against (NOT NULL)
....@@ -625,8 +672,8 @@
625672
626673 #define inc_wb_pos(wb) \
627674 do { \
628
- wb->pos = (wb->pos + 1) & (wb->size - 1); \
629
- wb->len = (wb->len + 1) & (wb->size - 1); \
675
+ wb->pos = (wb->pos + 1) & (WB_HISTORY_SIZE - 1); \
676
+ wb->len = (wb->len + 1) & (WB_HISTORY_SIZE - 1); \
630677 } while (0)
631678
632679 /* For DFAs that don't support extended tagging of states */
....@@ -645,7 +692,7 @@
645692 return true;
646693 }
647694 if (pos == 0)
648
- pos = wb->size;
695
+ pos = WB_HISTORY_SIZE;
649696 pos--;
650697 }
651698