xref: /netbsd-src/share/man/man9/secmodel.9 (revision 1ad9454efb13a65cd7535ccf867508cb14d9d30e)
1.\" $NetBSD: secmodel.9,v 1.6 2006/09/19 19:22:05 elad Exp $
2.\"
3.\" Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
4.\" All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\"    notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\"    notice, this list of conditions and the following disclaimer in the
13.\"    documentation and/or other materials provided with the distribution.
14.\" 3. All advertising materials mentioning features or use of this software
15.\"    must display the following acknowledgement:
16.\"      This product includes software developed by Elad Efrat.
17.\" 4. The name of the author may not be used to endorse or promote products
18.\"    derived from this software without specific prior written permission.
19.\"
20.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30.\"
31.Dd September 19, 2006
32.Dt SECMODEL 9
33.Os
34.Sh NAME
35.Nm secmodel
36.Nd security model development guidelines
37.Sh SYNOPSIS
38.In secmodel/secmodel.h
39.Sh DESCRIPTION
40.Nx
41provides a complete abstraction of the underlying security model used with
42the operating system to a set of
43.Xr kauth 9
44scopes and actions.
45.Pp
46It is possible to modify the security model -- either slightly or using an
47entirely different model -- by attaching/detaching
48.Xr kauth 9
49listeners.
50This document describes this process.
51.Ss Background
52In
53.Nx 4.0 ,
54Kernel Authorization --
55.Xr kauth 9
56-- was introduced as the subsystem responsible for authorization and
57credential management.
58Before its introduction, there were several ways for providing resource access
59control:
60.Bl -dash -offset indent -compact
61.It
62Checking if the user in question is the superuser via
63.Fn suser .
64.It
65Comparing the user-id against hard-coded values, often zero,
66.It
67Checking the system securelevel.
68.El
69.Pp
70The problem with the above is that the interface ("can X do Y?") was
71tightly coupled with the implementation ("is X Z?").
72.Xr kauth 9
73allowed us to separate them, dispatching requests with highly detailed
74context using
75a consistent and clear KPI.
76.Pp
77The result is a pluggable framework for attaching "listeners" that can
78modify the behavior of the system, security-wise.
79It allows us to maintain the existing security model (based on a single
80superuser and above-superuser restrictions known as securelevel) but easily
81decouple it from the system, given we want to use a different one.
82.Pp
83The different security model can be implemented in the kernel or loaded as an
84LKM, base its decisions on available information, dispatch the decision to a
85userspace daemon, or even to a centralized network authorization server.
86.Ss The kauth(9) KPI
87Before writing a new security model, one should be familiar with the
88.Xr kauth 9
89KPI, its limitations, requirements, and so on.
90.Pp
91First, some terminology.
92According to
93.Xr kauth 9 ,
94the system is logically divided to scopes, where each scope denotes a
95different area of interest in the system -- something like a namespace.
96For example,
97.Nx
98has the process, network, and machdep scopes, representing process-related,
99network-related, and machdep-related actions.
100.Pp
101Each scope has a collection of actions -- or requests -- forming the high
102level indication of the request type.
103Each request is automatically associated with credentials and between zero
104to four arguments providing the request context.
105.Pp
106For example, in the process scope there are requests such as "can signal",
107"can change rlimits", and "can change corename".
108.Pp
109Each scope in the system is associated with listeners, which are actually
110callback routines, that get called when an authorization request on the
111relevant scope takes place.
112.Pp
113Every listener receives the request and its context, and can make a decision
114of either "allow", "deny", or "defer" (if it doesn't want to be the one
115deciding).
116.Pp
117It is important to note that a single "deny" is enough to fail a request,
118and at least a single "allow" is required to allow it.
119In other words, it is impossible to attach listeners that weaken the security
120of the system or override decisions made by other listeners.
121.Pp
122At last, there are several things you should remember about
123.Xr kauth 9 :
124.Bl -dash -offset indent
125.It
126Authorization requests can not be issued when the kernel is holding any
127locks.
128This is a requirement from kernel code, to allow designing security models
129where the request should be dispatched to userspace or a different host.
130.It
131Private listener data -- such as internal data-structures -- is entirely
132under the resonsibility of the developer.
133Locking, synchronization, and garbage collection are all things that
134.Xr kauth 9
135does
136.Em not
137take care of for you!
138.El
139.Ss Writing a new security model
140A security model is composed of (code-wise) the following components:
141.Bl -enum -offset indent
142.It
143A
144.Fn secmodel_start
145routine, receiving and returning void.
146This routine registers the various listeners for the security model.
147.It
148An "init" routine, named
149.Fn secmodel_\*[Lt]model\*[Gt]_init ,
150receiving and returning void.
151This routine is used to initialize any private data-structures that may be
152used by the model.
153If none exist, it can be omitted.
154It should be called from
155.Fn secmodel_start .
156.It
157A sysctl(9) setup routine for the model.
158This should create an entry for the model in the
159.Xr sysctl 9
160namespace, under the "security.models.\*[Lt]model\*[Gt]" hierarchy.
161.It
162All "knobs" for the model should be located under the new node, as well
163as a mandatory "name" variable, indicating a descriptive human-readable
164name for the model.
165.It
166Optionally, internal data-structures used by the model. These must all
167be prefixed with "secmodel_\*[Lt]model\*[Lt]_".
168.It
169A set of listeners, attached to various scopes, used to enforce the policy
170the model intends to implement.
171.El
172.Pp
173Below is sample code for a
174.Xr kauth 9
175network scope listener for the
176.Em jenna
177security model.
178It is used to allow users with a user-id below 1000 bind to reserved ports
179(for example, 22/TCP):
180.Bd -literal -offset indent
181int
182secmodel_jenna_network_cb(kauth_cred_t cred, kauth_action_t action,
183    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
184{
185	int result;
186
187	/* Default defer. */
188	result = KAUTH_RESULT_DEFER;
189
190	switch (action) {
191	case KAUTH_NETWORK_BIND:
192		/*
193		 * We only care about bind(2) requests to privileged
194		 * ports.
195		 */
196		if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
197			/*
198			 * If the user-id is below 1000, which may
199			 * indicate a "reserved" user-id, allow the
200			 * request.
201			 */
202			if (kauth_cred_geteuid(cred) \*[Lt] 1000)
203				result = KAUTH_RESULT_ALLOW;
204		}
205		break;
206	}
207
208	return (result);
209}
210.Ed
211.Pp
212There are two main issues, however, with that listener, that you should be
213aware of when approaching to write your own security model:
214.Bl -enum -offset indent
215.It
216As mentioned,
217.Xr kauth 9
218uses restrictive decisions: if you attach this listener on-top of an existing
219security model, even if it would allow the request, it could still be failed.
220.It
221If you attach this listener as the only listener for the network scope,
222there are many other requests that will be deferred and, eventually,
223denied -- which may not be desired.
224.El
225.Pp
226That's why before implementing listeners, it should be clear whether they
227implement an entirely new from scratch security model, or add on-top of an
228existing one.
229.Ss Adding on-top of an existing security model
230One of the shortcomings of
231.Xr kauth 9
232is that it does not provide any stacking mechanism, similar to Linux Security
233Modules (LSM).
234This, however, is considered a feature in reducing dependency on other people's
235code.
236.Pp
237To properly "stack" minor adjustments on-top of an existing security model,
238one could use one of two approaches:
239.Bl -dash
240.It
241Registering an internal scope for the security model to be used as a
242fall-back when requests are deferred.
243.Pp
244This requires the security model developer to add an internal scope for
245every scope the model partly covers, and registering the fall-back
246listeners to it.
247In the model's listener(s) for the scope, when a defer decision is made, the
248request is passed to be authorized on the internal scope, effectively using
249the fall-back security model.
250.Pp
251Here's example code that implements the above:
252.Bd -literal -offset indent
253#include \*[Lt]secmodel/bsd44/bsd44.h\*[Gt]
254
255/*
256 * Internal fall-back scope for the network scope.
257 */
258#define	JENNA_ISCOPE_NETWORK "jenna.iscope.network"
259static kauth_scope_t secmodel_jenna_iscope_network;
260
261/*
262 * Jenna's entry point. Register internal scope for the network scope
263 * which we partly cover for fall-back authorization.
264 */
265void
266secmodel_jenna_start(void)
267{
268	secmodel_jenna_iscope_network = kauth_register_scope(
269	    JENNA_ISCOPE_NETWORK, NULL, NULL);
270
271	kauth_listen_scope(JENNA_ISCOPE_NETWORK,
272	    secmodel_bsd44_suser_network_cb, NULL);
273	kauth_listen_scope(JENNA_ISCOPE_NETWORK,
274	    secmodel_bsd44_securelevel_network_cb, NULL);
275}
276
277/*
278 * Jenna sits on top of another model, effectively filtering requests.
279 * If it has nothing to say, it discards the request. This is a good
280 * example for fine-tuning a security model for a special need.
281 */
282int
283secmodel_jenna_network_cb(kauth_cred_t cred, kauth_action_t action,
284    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
285{
286	int result;
287
288	/* Default defer. */
289	result = KAUTH_RESULT_DEFER;
290
291	switch (action) {
292	case KAUTH_NETWORK_BIND:
293		/*
294		 * We only care about bind(2) requests to privileged
295		 * ports.
296		 */
297		if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
298			if (kauth_cred_geteuid(cred) \*[Lt] 1000)
299				result = KAUTH_RESULT_ALLOW;
300		}
301		break;
302	}
303
304	/*
305	 * If we have don't have a decision, fall-back to the bsd44
306	 * security model.
307	 */
308	if (result == KAUTH_RESULT_DEFER)
309		result = kauth_authorize_action(
310		    secmodel_jenna_iscope_network, cred, action,
311		    arg0, arg1, arg2, arg3);
312
313	return (result);
314}
315.Ed
316.It
317If the above is not desired, or cannot be used for any reason, there is
318always the ability to manually call the fall-back routine:
319.Bd -literal -offset indent
320int
321secmodel_jenna_network_cb(kauth_cred_t cred, kauth_action_t action,
322    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
323{
324	int result;
325
326	/* Default defer. */
327	result = KAUTH_RESULT_DEFER;
328
329	switch (action) {
330	case KAUTH_NETWORK_BIND:
331		/*
332		 * We only care about bind(2) requests to privileged
333		 * ports.
334		 */
335		if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
336			if (kauth_cred_geteuid(cred) \*[Lt] 1000)
337				result = KAUTH_RESULT_ALLOW;
338		}
339		break;
340	}
341
342	/*
343	 * If we have don't have a decision, fall-back to the bsd44
344	 * security model's suser behavior.
345	 */
346	if (result == KAUTH_RESULT_DEFER)
347		result = secmodel_bsd44_suser_network_cb(cred, action,
348		    cookie, arg0, arg1, arg2, arg3);
349
350	return (result);
351}
352.Ed
353.El
354.Ss Writing a new security model from scratch
355When writing a security model from scratch, aside from the obvious issues of
356carefully following the desired policy to be implemented and paying attention
357to all of the issues outlined above, one must also remember that any unhandled
358requests will be denied by default.
359.Pp
360To make it easier on developers to write new security models from scratch,
361.Nx
362maintains skeleton listeners that contain every possible request and
363arguments.
364.Ss Available security models
365The following is a list of security models available in the default
366.Nx
367distribution.
368To choose, one should edit
369.Pa /usr/src/sys/conf/std .
370.Bl -tag -hyphen
371.It secmodel_bsd44
372Traditional
373.Nx
374security model, derived from
375.Bx 4.4 .
376.It secmodel_overlay
377Sample overlay security model, sitting on-top of
378.Xr secmodel_bsd44 9 .
379.El
380.Sh FILES
381.Pa /usr/share/examples/secmodel
382.Sh SEE ALSO
383.Xr kauth 9 ,
384.Xr secmodel_bsd44 9 ,
385.Xr secmodel_overlay 9
386.Sh AUTHORS
387.An Elad Efrat Aq elad@NetBSD.org
388