From 27d738c874824a49995b83815a15f7fa2466f721 Mon Sep 17 00:00:00 2001 From: John Johansen Date: Wed, 7 Dec 2022 18:08:12 -0800 Subject: [PATCH] parser: Fix invalid reference to transitions when building the chfa States are not guaranteed to have transitions, but when inserting a state into the chfa table there is an unconditional dereference to the states first transition. This will result in a bad reference and could result in an OOB flag being set on the state when it shouldn't be. Fixes: 16b67ddbd ("add ability to use out of band transitions" Closes: https://gitlab.com/apparmor/apparmor/-/issues/290 Reported-by: Nobel Barakat Reported-by: Oleksandr Tymoshenko Signed-off-by: John Johansen --- parser/libapparmor_re/chfa.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/parser/libapparmor_re/chfa.cc b/parser/libapparmor_re/chfa.cc index 55adfbf7d..235df335b 100644 --- a/parser/libapparmor_re/chfa.cc +++ b/parser/libapparmor_re/chfa.cc @@ -193,9 +193,8 @@ void CHFA::insert_state(vector > &free_list, State *default_state = dfa.nonmatching; ssize_t base = 0; int resize; - StateTrans &trans = from->trans; - ssize_t c = trans.begin()->first.c; + ssize_t c; ssize_t prev = 0; ssize_t x = first_free; @@ -204,6 +203,7 @@ void CHFA::insert_state(vector > &free_list, if (trans.empty()) goto do_insert; + c = trans.begin()->first.c; repeat: resize = 0; /* get the first free entry that won't underflow */ @@ -251,10 +251,18 @@ repeat: first_free = next; } -do_insert: + /* these flags will only be set on states that have transitions */ if (c < 0) { base |= MATCH_FLAG_OOB_TRANSITION; } +do_insert: + /* While a state without transitions could have the diff encode + * flag set, it would be pointless resulting in just an extra + * state transition in the encoding chain, and so it should be + * considered an error + * TODO: add check that state without transitions isn't being + * given a diffencode flag + */ if (from->flags & DiffEncodeFlag) base |= DiffEncodeBit32; default_base.push_back(make_pair(default_state, base));