No empty .Rs/.Re
[netbsd-mini2440.git] / share / man / man9 / secmodel.9
blob502511cae9d1f15828390987a0dbbc2a9616ec89
1 .\" $NetBSD: secmodel.9,v 1.15 2009/05/10 14:18:33 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. The name of the author may not be used to endorse or promote products
15 .\"    derived from this software without specific prior written permission.
16 .\"
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.
27 .\"
28 .Dd May 10, 2009
29 .Dt SECMODEL 9
30 .Os
31 .Sh NAME
32 .Nm secmodel
33 .Nd security model development guidelines
34 .Sh SYNOPSIS
35 .In secmodel/secmodel.h
36 .Sh DESCRIPTION
37 .Nx
38 provides a complete abstraction of the underlying security model used with
39 the operating system to a set of
40 .Xr kauth 9
41 scopes and actions.
42 .Pp
43 It is possible to modify the security model -- either slightly or using an
44 entirely different model -- by attaching/detaching
45 .Xr kauth 9
46 listeners.
47 This document describes this process.
48 .Ss Background
50 .Nx 4.0 ,
51 Kernel Authorization --
52 .Xr kauth 9
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
56 control:
57 .Bl -dash -offset indent -compact
58 .It
59 Checking if the user in question is the superuser via
60 .Fn suser .
61 .It
62 Comparing the user-id against hard-coded values, often zero,
63 .It
64 Checking the system securelevel.
65 .El
66 .Pp
67 The problem with the above is that the interface ("can X do Y?") was
68 tightly coupled with the implementation ("is X Z?").
69 .Xr kauth 9
70 allowed us to separate them, dispatching requests with highly detailed
71 context using
72 a consistent and clear KPI.
73 .Pp
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.
79 .Pp
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.
83 .Ss The kauth(9) KPI
84 Before writing a new security model, one should be familiar with the
85 .Xr kauth 9
86 KPI, its limitations, requirements, and so on.
87 .Pp
88 First, some terminology.
89 According to
90 .Xr kauth 9 ,
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.
93 For example,
94 .Nx
95 has the process, network, and machdep scopes, representing process-related,
96 network-related, and machdep-related actions.
97 .Pp
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
112 deciding).
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
120 .Xr kauth 9 :
121 .Bl -dash -offset indent
123 Authorization requests can not be issued when the kernel is holding any
124 locks.
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
131 .Xr kauth 9
132 does
133 .Em not
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
148 .Fn secmodel_start
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
152 called
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
158 .Xr sysctl 9
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
163 name for the model.
165 If the module is to be used as a module, explicit calls to the setup
166 routine and
167 .Fn sysctl_teardown
168 are to be used to create and destroy the
169 .Xr sysctl 9
170 tree.
172 If the model uses any private data inside credentials, listening on
173 the credentials scope,
174 .Dv KAUTH_SCOPE_CRED ,
175 is required.
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
190 .Xr kauth 9
191 network scope listener for the
192 .Em jenna
193 security model.
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)
201         int result;
203         /* Default defer. */
204         result = KAUTH_RESULT_DEFER;
206         switch (action) {
207         case KAUTH_NETWORK_BIND:
208                 /*
209                  * We only care about bind(2) requests to privileged
210                  * ports.
211                  */
212                 if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
213                         /*
214                          * If the user-id is below 1000, which may
215                          * indicate a "reserved" user-id, allow the
216                          * request.
217                          */
218                         if (kauth_cred_geteuid(cred) \*[Lt] 1000)
219                                 result = KAUTH_RESULT_ALLOW;
220                 }
221                 break;
222         }
224         return (result);
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
232 As mentioned,
233 .Xr kauth 9
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
244 existing one.
245 .Ss Adding on-top of an existing security model
246 One of the shortcomings of
247 .Xr kauth 9
248 is that it does not provide any stacking mechanism, similar to Linux Security
249 Modules (LSM).
250 This, however, is considered a feature in reducing dependency on other people's
251 code.
253 To properly "stack" minor adjustments on-top of an existing security model,
254 one could use one of two approaches:
255 .Bl -dash
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
262 listeners to it.
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.
273  */
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.
280  */
281 void
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.
297  */
299 secmodel_jenna_network_cb(kauth_cred_t cred, kauth_action_t action,
300     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
302         int result;
304         /* Default defer. */
305         result = KAUTH_RESULT_DEFER;
307         switch (action) {
308         case KAUTH_NETWORK_BIND:
309                 /*
310                  * We only care about bind(2) requests to privileged
311                  * ports.
312                  */
313                 if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
314                         if (kauth_cred_geteuid(cred) \*[Lt] 1000)
315                                 result = KAUTH_RESULT_ALLOW;
316                 }
317                 break;
318         }
320         /*
321          * If we have don't have a decision, fall-back to the bsd44
322          * security model.
323          */
324         if (result == KAUTH_RESULT_DEFER)
325                 result = kauth_authorize_action(
326                     secmodel_jenna_iscope_network, cred, action,
327                     arg0, arg1, arg2, arg3);
329         return (result);
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)
340         int result;
342         /* Default defer. */
343         result = KAUTH_RESULT_DEFER;
345         switch (action) {
346         case KAUTH_NETWORK_BIND:
347                 /*
348                  * We only care about bind(2) requests to privileged
349                  * ports.
350                  */
351                 if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
352                         if (kauth_cred_geteuid(cred) \*[Lt] 1000)
353                                 result = KAUTH_RESULT_ALLOW;
354                 }
355                 break;
356         }
358         /*
359          * If we have don't have a decision, fall-back to the bsd44
360          * security model's suser behavior.
361          */
362         if (result == KAUTH_RESULT_DEFER)
363                 result = secmodel_bsd44_suser_network_cb(cred, action,
364                     cookie, arg0, arg1, arg2, arg3);
366         return (result);
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
379 arguments.
380 .Ss Available security models
381 The following is a list of security models available in the default
383 distribution.
384 To choose, one should edit
385 .Pa /usr/src/sys/conf/std .
386 .Bl -tag -width secmodel_overlay
387 .It secmodel_bsd44
388 Traditional
390 security model, derived from
391 .Bx 4.4 .
392 .It secmodel_overlay
393 Sample overlay security model, sitting on-top of
394 .Xr secmodel_bsd44 9 .
396 .Sh FILES
397 .Pa /usr/share/examples/secmodel
398 .Sh SEE ALSO
399 .Xr kauth 9 ,
400 .Xr secmodel_bsd44 9 ,
401 .Xr secmodel_overlay 9
402 .Sh AUTHORS
403 .An Elad Efrat Aq elad@NetBSD.org