policycoreutils: pp: mimic require block support in CIL

CIL does not have any concept of require blocks. Instead, CIL relies on
whether or not all statements inside an optional block resolve to
determine if an optional block should be enabled/disabled. However, a
small number of optional statements require a type that is not actually
used in the optional block. In old style policy, this would cause the
optional block to be disabled. However, in CIL, because the type is never
used, the optional block will remain enabled.

To maintain compatibility, we modify pp2cil to create a new attribute,
cil_gen_require, and all types/roles/attributes that are required in a
pp module/optional block are associated with this attribute. Thus, if a
type is required but not used, it will still fail to resolve in the
typeattributeset statement, causing the optional to correctly be
disabled.

Note that when compiling the CIL this generated from compiling refpolicy
pp modules with pp2cil, the extra CIL statements cause ~12.6MB increase
in maximum memory usage (129.7 MB to 142.3 MB). Though, compilation time
decreases by ~35% (26 seconds to 17 seconds).

Signed-off-by: Steve Lawrence <slawrence@tresys.com>
Reviewed-by: Yuli Khodorkovskiy <ykhodorkovskiy@tresys.com>
Reported-by: Sven Vermeulen <sven.vermeulen@siphos.be>
1 file changed