On Fri, 2019-04-26 at 18:57 +0200, Pablo Neira Ayuso wrote: > > > +/* > > + * Nested policies might refer back to the original > > + * policy in some cases, and userspace could try to > > + * abuse that and recurse by nesting in the right > > + * ways. Limit recursion to avoid this problem. > > + */ > > +#define MAX_POLICY_RECURSION_DEPTH 10 > > In your policy description approach, you iterate over the policy > structures. How do you deal with this recursions from there?
Well, check out the code :-) It doesn't actually recurse. What it does is build a list of policies that are reachable from the root policy and each policy in the list. So basically, there we do: list = [root policy] list_len = 1 i = 0 walk_policy(policy) { for_each_policy_entry(entry, policy) { nested = nested_policy_or_null(entry); if (nested) { list[i] = nested; list_len += 1 } } } while (i < list_len) { walk_policy(list[i]); i++; } Then, we walk the list again: for (i = 0; i < list_len; i++) { for_each_policy_entry(entry, list[i]) { send_entry_to_userspace(i, entry); // mark it as occurring in policy i } } This basically flattens the whole thing. Obviously, the walking may allocate some memory, and the last loop to send it out isn't actually a loop like that because it's a netlink dump with each entry being in a separate netlink message, but that's the gist of it. johannes