1 .\" $NetBSD: secmodel.9,v 1.15 2009/05/10 14:18:33 elad Exp $
3 .\" Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
4 .\" All rights reserved.
6 .\" Redistribution and use in source and binary forms, with or without
7 .\" modification, are permitted provided that the following conditions
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. The name of the author may not be used to endorse or promote products
15 .\" derived from this software without specific prior written permission.
17 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 .\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 .\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 .\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 .\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 .\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 .Nd security model development guidelines
35 .In secmodel/secmodel.h
38 provides a complete abstraction of the underlying security model used with
39 the operating system to a set of
43 It is possible to modify the security model -- either slightly or using an
44 entirely different model -- by attaching/detaching
47 This document describes this process.
51 Kernel Authorization --
53 -- was introduced as the subsystem responsible for authorization and
54 credential management.
55 Before its introduction, there were several ways for providing resource access
57 .Bl -dash -offset indent -compact
59 Checking if the user in question is the superuser via
62 Comparing the user-id against hard-coded values, often zero,
64 Checking the system securelevel.
67 The problem with the above is that the interface ("can X do Y?") was
68 tightly coupled with the implementation ("is X Z?").
70 allowed us to separate them, dispatching requests with highly detailed
72 a consistent and clear KPI.
74 The result is a pluggable framework for attaching "listeners" that can
75 modify the behavior of the system, security-wise.
76 It allows us to maintain the existing security model (based on a single
77 superuser and above-superuser restrictions known as securelevel) but easily
78 decouple it from the system, given we want to use a different one.
80 The different security model can be implemented in the kernel or loaded as a
81 module, base its decisions on available information, dispatch the decision to a
82 userspace daemon, or even to a centralized network authorization server.
84 Before writing a new security model, one should be familiar with the
86 KPI, its limitations, requirements, and so on.
88 First, some terminology.
91 the system is logically divided to scopes, where each scope denotes a
92 different area of interest in the system -- something like a namespace.
95 has the process, network, and machdep scopes, representing process-related,
96 network-related, and machdep-related actions.
98 Each scope has a collection of actions -- or requests -- forming the high
99 level indication of the request type.
100 Each request is automatically associated with credentials and between zero
101 to four arguments providing the request context.
103 For example, in the process scope there are requests such as "can signal",
104 "can change rlimits", and "can change corename".
106 Each scope in the system is associated with listeners, which are actually
107 callback routines, that get called when an authorization request on the
108 relevant scope takes place.
110 Every listener receives the request and its context, and can make a decision
111 of either "allow", "deny", or "defer" (if it doesn't want to be the one
114 It is important to note that a single "deny" is enough to fail a request,
115 and at least a single "allow" is required to allow it.
116 In other words, it is impossible to attach listeners that weaken the security
117 of the system or override decisions made by other listeners.
119 At last, there are several things you should remember about
121 .Bl -dash -offset indent
123 Authorization requests can not be issued when the kernel is holding any
125 This is a requirement from kernel code, to allow designing security models
126 where the request should be dispatched to userspace or a different host.
128 Private listener data -- such as internal data-structures -- is entirely
129 under the responsibility of the developer.
130 Locking, synchronization, and garbage collection are all things that
134 take care of for you!
136 .Ss Writing a new security model
137 A security model is composed of (code-wise) the following components:
138 .Bl -enum -offset indent
140 Entry routines, named
141 .Fn secmodel_\*[Lt]model\*[Gt]_init
143 .Fn secmodel_\*[Lt]model\*[Gt]_start ,
144 used to initialize and start the security model.
146 If the security model is to be started automatically by the kernel and is
147 compiled in it, a function called
149 can be added to call the model's start routine.
151 If the security model is to be built and used as a module, another function
153 .Fn secmodel_\*[Lt]model\*[Gt]_stop ,
154 to stop the security model in case the module is to be unloaded.
156 A sysctl(9) setup routine for the model.
157 This should create an entry for the model in the
159 namespace, under the "security.models.\*[Lt]model\*[Gt]" hierarchy.
161 All "knobs" for the model should be located under the new node, as well
162 as a mandatory "name" variable, indicating a descriptive human-readable
165 If the module is to be used as a module, explicit calls to the setup
168 are to be used to create and destroy the
172 If the model uses any private data inside credentials, listening on
173 the credentials scope,
174 .Dv KAUTH_SCOPE_CRED ,
177 Optionally, internal data-structures used by the model.
178 These must all be prefixed with "secmodel_\*[Lt]model\*[Gt]_".
180 A set of listeners, attached to various scopes, used to enforce the policy
181 the model intends to implement.
183 Finally, a security model should register itself when loaded using
184 .Fn secmodel_register
185 and deregister it when unloaded (if used as a module) using
186 .Fn secmodel_deregister .
189 Below is sample code for a
191 network scope listener for the
194 It is used to allow users with a user-id below 1000 bind to reserved ports
195 (for example, 22/TCP):
196 .Bd -literal -offset indent
198 secmodel_jenna_network_cb(kauth_cred_t cred, kauth_action_t action,
199 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
204 result = KAUTH_RESULT_DEFER;
207 case KAUTH_NETWORK_BIND:
209 * We only care about bind(2) requests to privileged
212 if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
214 * If the user-id is below 1000, which may
215 * indicate a "reserved" user-id, allow the
218 if (kauth_cred_geteuid(cred) \*[Lt] 1000)
219 result = KAUTH_RESULT_ALLOW;
228 There are two main issues, however, with that listener, that you should be
229 aware of when approaching to write your own security model:
230 .Bl -enum -offset indent
234 uses restrictive decisions: if you attach this listener on-top of an existing
235 security model, even if it would allow the request, it could still be failed.
237 If you attach this listener as the only listener for the network scope,
238 there are many other requests that will be deferred and, eventually,
239 denied -- which may not be desired.
242 That's why before implementing listeners, it should be clear whether they
243 implement an entirely new from scratch security model, or add on-top of an
245 .Ss Adding on-top of an existing security model
246 One of the shortcomings of
248 is that it does not provide any stacking mechanism, similar to Linux Security
250 This, however, is considered a feature in reducing dependency on other people's
253 To properly "stack" minor adjustments on-top of an existing security model,
254 one could use one of two approaches:
257 Registering an internal scope for the security model to be used as a
258 fall-back when requests are deferred.
260 This requires the security model developer to add an internal scope for
261 every scope the model partly covers, and registering the fall-back
263 In the model's listener(s) for the scope, when a defer decision is made, the
264 request is passed to be authorized on the internal scope, effectively using
265 the fall-back security model.
267 Here's example code that implements the above:
268 .Bd -literal -offset indent
269 #include \*[Lt]secmodel/bsd44/bsd44.h\*[Gt]
272 * Internal fall-back scope for the network scope.
274 #define JENNA_ISCOPE_NETWORK "jenna.iscope.network"
275 static kauth_scope_t secmodel_jenna_iscope_network;
278 * Jenna's entry point. Register internal scope for the network scope
279 * which we partly cover for fall-back authorization.
282 secmodel_jenna_start(void)
284 secmodel_jenna_iscope_network = kauth_register_scope(
285 JENNA_ISCOPE_NETWORK, NULL, NULL);
287 kauth_listen_scope(JENNA_ISCOPE_NETWORK,
288 secmodel_bsd44_suser_network_cb, NULL);
289 kauth_listen_scope(JENNA_ISCOPE_NETWORK,
290 secmodel_securelevel_network_cb, NULL);
294 * Jenna sits on top of another model, effectively filtering requests.
295 * If it has nothing to say, it discards the request. This is a good
296 * example for fine-tuning a security model for a special need.
299 secmodel_jenna_network_cb(kauth_cred_t cred, kauth_action_t action,
300 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
305 result = KAUTH_RESULT_DEFER;
308 case KAUTH_NETWORK_BIND:
310 * We only care about bind(2) requests to privileged
313 if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
314 if (kauth_cred_geteuid(cred) \*[Lt] 1000)
315 result = KAUTH_RESULT_ALLOW;
321 * If we have don't have a decision, fall-back to the bsd44
324 if (result == KAUTH_RESULT_DEFER)
325 result = kauth_authorize_action(
326 secmodel_jenna_iscope_network, cred, action,
327 arg0, arg1, arg2, arg3);
333 If the above is not desired, or cannot be used for any reason, there is
334 always the ability to manually call the fall-back routine:
335 .Bd -literal -offset indent
337 secmodel_jenna_network_cb(kauth_cred_t cred, kauth_action_t action,
338 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
343 result = KAUTH_RESULT_DEFER;
346 case KAUTH_NETWORK_BIND:
348 * We only care about bind(2) requests to privileged
351 if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
352 if (kauth_cred_geteuid(cred) \*[Lt] 1000)
353 result = KAUTH_RESULT_ALLOW;
359 * If we have don't have a decision, fall-back to the bsd44
360 * security model's suser behavior.
362 if (result == KAUTH_RESULT_DEFER)
363 result = secmodel_bsd44_suser_network_cb(cred, action,
364 cookie, arg0, arg1, arg2, arg3);
370 .Ss Writing a new security model from scratch
371 When writing a security model from scratch, aside from the obvious issues of
372 carefully following the desired policy to be implemented and paying attention
373 to all of the issues outlined above, one must also remember that any unhandled
374 requests will be denied by default.
376 To make it easier on developers to write new security models from scratch,
378 maintains skeleton listeners that contain every possible request and
380 .Ss Available security models
381 The following is a list of security models available in the default
384 To choose, one should edit
385 .Pa /usr/src/sys/conf/std .
386 .Bl -tag -width secmodel_overlay
390 security model, derived from
393 Sample overlay security model, sitting on-top of
394 .Xr secmodel_bsd44 9 .
397 .Pa /usr/share/examples/secmodel
400 .Xr secmodel_bsd44 9 ,
401 .Xr secmodel_overlay 9
403 .An Elad Efrat Aq elad@NetBSD.org