The unlocked_security_compute_av function sets the sequence number to the value of latest_granting, a global counter that is incremented by the security_load_policy function when a new policy configuration is loaded. Then, the function sets the decided vector to contain all permissions, since none of the policies implemented by the security server prototype defer the computation of any permissions.
If the security server has not yet initialized, then the unlocked_security_compute_av function simply returns the requested permissions in both the decided vector and the allowed vector. Hence, all requested permissions are granted until the initialization of the security server has completed. This is necessary because some permission checks occur before the security_init function is called, e.g. fork permission for kernel threads and create permission for the ICMP socket and the TCP reset socket. Additionally, a search permission check occurs when the security_init function opens the policy configuration file.
A more secure solution would be to preload the security server state or the access vector cache state with the exact set of permissions that are required to initialize. This initial state could then be included in the analysis of the overall security policy. However, since the system is still under development, the full initial state is not yet known.
If the security server has initialized, then the unlocked_security_compute_av function looks up the security contexts for the SID pair in the SID hash table (sidtab.h:sidtab_t). These security contexts are stored using a structure that is private to the security server (context.h:context_struct_t). The function then looks up the attributes associated with the class (policydb.h:class_datum_t).
The function sets the values of the access vectors to their default values. It then looks for an access vector rule in the TE access vector table (avtab.h:avtab_t) for the type pair and class. If a rule exists, then the function sets the corresponding access vectors to the vectors specified by the rule.
If the MLS policy is enabled, the function then calls the MLS policy (mls.c:mls_compute_av) to remove any permissions from the allowed vector that are prohibited by the MLS policy. The MLS policy removes any permissions from allowed that are mapped to a MLS base permission that would be denied.
The function then checks the list of constraints associated with the class for any constraints that apply to the permissions in allowed. The constraint_expr_eval function is invoked on each such constraint. If the constraint evaluates to false, then the function removes the constrained permissions from allowed.
If the process transition permission is being computed and the role is changing, then the function looks for a role allow rule that authorizes the role transition. If no such rule exists, then the process transition permission is denied.