On Fri, Apr 26, 2019 at 07:03:10PM +0200, Johannes Berg wrote: > 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.
I see, following this approach, I can just remove the duplicated code in my netlink description stuff by using the list of policy structures.