• No results found

3.5 Architecture of the MAC Framework

3.5.5 Policy entry point invocation

The MAC Framework functionmac vnode check write, responsible for invoking policies

and composing their results forvnodewrite operations, is illustrated in Figure 3.4. The

MAC_CHECK_PROBE_DEFINE3(vnode_check_write, "struct ucred *", "struct ucred *", "struct vnode *");

int

mac_vnode_check_write(struct ucred *active_cred, struct ucred *file_cred, struct vnode *vp) {

int error;

ASSERT_VOP_LOCKED(vp, "mac_vnode_check_write");

MAC_POLICY_CHECK(vnode_check_write, active_cred, file_cred, vp, vp->v_label);

MAC_CHECK_PROBE3(vnode_check_write, error, active_cred, file_cred, vp);

return (error); }

Figure 3.4: The MAC Framework implements mac vnode check write: the locking protocol is validated, policies are invoked and composed using MAC POLICY CHECK, and a DTrace probe is fired on completion.

kernel service is observing the synchronisation protocol for labels and policy enforce- ment. Normally, assertions are compiled out of production FreeBSD kernels, but may be compiled in to provide fail-stop semantics when certain classes of synchronisation bugs are encountered.

Next, mac vnode check write invokes MAC POLICY CHECK, which is responsible for busying the framework to stabilise the policy set, invoking each interested policy, com- posing the results, and invoking a DTrace probe that corresponds to the entry point. One notable difference between the kernel services KPI and the policy KPI is that the framework also passes pointers to object labels into policies, not just the objects themselves. This avoids embedding binary layout assumptions about the structure in order for a policy to access its labels. The policy framework arranges that only policies implementing an entry point are invoked – it also analyses the entry points declared by a policy in order to optimise its own behaviour, for example with respect to labelling. Discussion of the evolution of labelling optimisations and further consideration of the KBI resilience issue may be found in Chapter 4.

In addition to policy entry points mapped from MAC Framework entry points, there are several types of entry points to the policy that are not derived in the MAC Framework KPI, including policy registration and deregistration, label query and modi- fication system calls, and the dedicatedmac syscall. These entry points are all invoked

from within the MAC Framework, but via utility functions with similar structure and contents to mac vnode check write.

Operating system kernel MAC Framework Process signals Biba MLS ugidfw ma c_ e rro r_ se le ct ma c_ p ro c_ ch e ck_ si g n a l ESR CH 0 EAC CES ESRCH Process ESRCH ki ll

Figure 3.5: For access control checks, the results of individual policy checks are composed by mac error select, which implements a precedence operator to select which of several differing error results is the one to be returned by the system call.

3.5.6 Policy composition

Kernel entry points will invoke at least one, and possibly multiple, policy entry points. The act of policy entry point invocation is non-trivial: access to the policy list must be synchronised to prevent races with policy load and unload, the subset of policies interested in the event must have their entry point implementations called, and the results of those calls must be sensibly composed. In the original Poligraph design, this composition is controlled by a configurable meta-policy able to capture the rela- tionship between privilege models, discretionary access control models, and mandatory access control models. In the MAC Framework design, only policies limiting the rights granted to subjects relative to the base access control policy are supported, requiring a much simpler composition in which the set of rights granted is the intersection of rights granted across all registered policies. This meta-policy is simple, deterministic, predictable by developers, and above all, useful.

Policy entry points may be broadly categorised into three types based on return type: event notifications that do not return a value, access control checks that return anerrnovalue, and general decision functions that return a boolean. The composition policy requires that for an access control check to succeed, all policies expressing interest in the entry point must return success; as policies may return different error numbers in response to the same access control check, a composition function,mac error select

orders and selects from among available error values. Invocation of policy entry points and composition of the results are performed using a set of composition macros10 which

10A further composition macro,

MAC POLICY GRANT, was added in FreeBSD 7.0 to allow policies to grant privileges; this change is detailed in Chapter 4.

combine synchronisation, selective policy invocation, and composition:

• MAC POLICY PERFORMcomposes policy entry points that have no return value, and is used to post events to interested policies. These events relate to policy changes, label management, policy management, or kernel object life cycle events. Since there are no return values, there is no need to provide for their composition.

• MAC POLICY CHECK composes the results of access control entry points. Unlike

MAC POLICY PERFORM, it accepts an errno return value from each policy and com- poses the results using mac error select, a function that encodes an ordering of various failure classes. This model is illustrated in Figure 3.5.

• MAC POLICY BOOLEAN composes the results of decision entry points returning true and false values. It is used in scenarios where policies augment an existing kernel service decision rather than returning an access control success or failure. For example, during IP fragment reassembly, MAC policies labelling IP packets must decide if each received IP fragment matches IP fragment queues as they are it- erated over. In this case, MAC POLICY BOOLEAN is used with a boolean and: all policies must accept a match in order for the framework to return true.

Some MAC Framework operations invoke more than one entry point during their operation; for example, a label set system call will need to allocate and initialise tem- porary label storage for the object type, copy in and internalize the userspace version of the label, perform an access control, set the label, and free the temporary storage. This sequence supports one of the more interesting aspects of policy composition: a two-phase commit on relabelling operations. This allows one policy to provide access control logic limiting the setting of labels associated with another policy on an object; for example, the Biba policy can prevent MLS labels from being set on a high-integrity object by a low-integrity subject.