xref: /netbsd-src/share/man/man9/secmodel.9 (revision 7c674e8e6e818717bee65b1f985c9e2a9f0126bd)
1.\" $NetBSD: secmodel.9,v 1.23 2022/01/26 11:48:53 andvar 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 December 4, 2011
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.Ft int
37.Fn secmodel_register "secmodel_t *sm" "const char *id" "const char *name" \
38    "prop_dictionary_t behavior" "secmodel_eval_t sm_eval" \
39    "secmodel_setinfo_t sm_setinfo"
40.Ft int
41.Fn secmodel_deregister "secmodel_t sm"
42.Ft int
43.Fn secmodel_eval "const char *id" "const char *what" "void *arg" "void *ret"
44.Ft static int
45.Fn secmodel_<model>_eval "const char *what" "void *arg" \
46    "void *ret"
47.Sh DESCRIPTION
48.Nx
49provides a complete abstraction of the underlying security model used within
50the operating system through a set of
51.Xr kauth 9
52scopes and actions.
53It allows maintaining the traditional security model (based on a single
54.Em super-user
55and above-super-user restrictions known as
56.Em securelevel )
57while decoupling it easily from the system.
58.Pp
59It is possible to modify the security model \(em either slightly or
60using an entirely different model \(em by attaching/detaching
61.Xr kauth 9
62listeners.
63This can be done via the
64.Nm
65pluggable framework.
66.Pp
67A
68.Nm
69is typically implemented as a kernel
70.Xr module 9 ,
71and can be either built-in statically or loaded dynamically at run-time.
72They base their decisions on available information, either directly from
73kernel, from a userspace daemon or even from a centralized network
74authorization server.
75.Sh DATA TYPES
76The
77.Nm
78framework offers the following data types:
79.Bl -tag -width secmodel_t
80.It Fa secmodel_t
81An opaque type that describes a
82.Nm .
83.El
84.Sh FUNCTIONS
85.Bl -tag -width xxxxxxx
86.It Fn secmodel_register "sm" "id" "name" "behavior" "sm_eval" "sm_setinfo"
87Register a security model to the
88.Nm
89framework and stores its description inside
90.Fa sm .
91.Bl -tag -width sm_setinfo
92.It Fa sm
93The
94.Nm
95description.
96.It Fa id
97The unique identifier of the
98.Nm .
99.It Fa name
100The descriptive human-readable name of the
101.Nm .
102.It Fa behavior
103(optional) a
104.Xr prop_dictionary 3
105that declares the behavior of this security model, like
106.Do copy credentials on fork . Dc
107.It Fa sm_eval
108(optional) the
109.Fn secmodel_<model>_eval
110callback used by a
111.Nm
112to register an evaluation routine that can be queried later
113by another security model.
114.It Fa sm_setinfo
115(optional) the
116.Fn secmodel_<model>_setinfo
117callback used by a
118.Nm
119to register a routine that permits other security models to
120alter the
121.Nm
122internals.
123Currently not implemented.
124.El
125.It Fn secmodel_deregister "sm"
126Deregister the
127.Nm
128described by
129.Fa sm .
130.It Fn secmodel_eval "id" "what" "arg" "ret"
131Call the evaluation callback implemented by a security model.
132The return value can be either:
133.Bl -dash -compact -offset xxxxxx
134.It
135zero (0), when the call succeeded.
136.It
137positive, when the error comes directly from the
138.Nm
139framework.
140.It
141negative, when the error comes from the evaluation callback
142implemented in the targeted security model.
143The value is then implementation-defined.
144.El
145.Pp
146.Bl -tag -width what
147.It Fa id
148The unique identifier of the targeted
149.Nm .
150.It Fa what
151The query that will be passed down to the targeted
152.Nm .
153.It Fa arg
154The arguments passed to the evaluation routine of the targeted
155.Nm .
156.It Fa ret
157The answer of the evaluation routine.
158.El
159.El
160.Sh RETURN VALUES
161If successful, functions return 0.
162Otherwise, the following error values are returned:
163.Bl -tag -width [EINVAL]
164.It Bq Er EEXIST
165The
166.Nm
167is already registered.
168.It Bq Er EFAULT
169An invalid address or reference was passed as parameter.
170.It Bq Er EINVAL
171An invalid value was passed as parameter.
172.It Bq Er ENOENT
173The targeted
174.Nm
175does not exist, or it does not implement an evaluation callback.
176.El
177.Sh WRITING A SECURITY MODEL
178Before writing a security model one should be familiar with the
179.Xr kauth 9
180KPI, its limitations, requirements, and so on.
181See
182.Xr kauth 9
183for details.
184.Pp
185A security model is based on the kernel
186.Xr module 9
187framework, and can be built-in statically inside kernel or
188loaded dynamically at run-time.
189It is composed of (code-wise) the following components:
190.Bl -enum -offset indent
191.It
192.Xr module 9
193routines, especially a
194.Fn MODULE
195declaration and a
196.Fn secmodel_<model>_modcmd
197function used to start
198.Po through Dv MODULE_CMD_INIT Pc
199and stop
200.Po through Dv MODULE_CMD_FINI Pc
201the
202.Nm .
203.It
204Entry routines, named
205.Fn secmodel_<model>_init
206and
207.Fn secmodel_<model>_start ,
208used to initialize and start the security model, and another
209function called
210.Fn secmodel_<model>_stop ,
211to stop the security model in case the module is to be unloaded.
212.It
213A
214.Xr sysctl 9
215setup routine for the model.
216This should create an entry for the model in the
217.Xr sysctl 7
218namespace, under the "security.models.<model>" hierarchy.
219.Pp
220All "knobs" for the model should be located under the new node, as well
221as a mandatory
222.Fa name
223variable, indicating a descriptive human-readable
224name for the model.
225.It
226A
227.Xr sysctl 9
228teardown routine used to destroy the
229.Xr sysctl 7
230tree associated with the model.
231.It
232If the model uses any private data inside credentials, listening on
233the credentials scope,
234.Dv KAUTH_SCOPE_CRED ,
235is required.
236.It
237Optionally, internal data-structures used by the model.
238These must all be prefixed with "secmodel_<model>_".
239.It
240A set of listeners, attached to various scopes, used to enforce the policy
241the model intends to implement.
242.It
243Finally, a security model should register itself after being
244initialized using
245.Fn secmodel_register ,
246and deregister itself before being stopped using
247.Fn secmodel_deregister .
248.El
249.Sh EXAMPLES
250Below is sample code for a
251.Xr kauth 9
252network scope listener for the
253.Em jenna
254security model.
255It is used to allow users with a user-id below 1000 to bind to reserved ports
256(for example, 22/TCP):
257.Bd -literal
258int
259secmodel_jenna_network_cb(kauth_cred_t cred, kauth_action_t action,
260    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
261{
262	int result;
263
264	/* Default defer. */
265	result = KAUTH_RESULT_DEFER;
266
267	switch (action) {
268	case KAUTH_NETWORK_BIND:
269		/*
270		 * We only care about bind(2) requests to privileged
271		 * ports.
272		 */
273		if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
274			/*
275			 * If the user-id is below 1000, which may
276			 * indicate a "reserved" user-id, allow the
277			 * request.
278			 */
279			if (kauth_cred_geteuid(cred) < 1000)
280				result = KAUTH_RESULT_ALLOW;
281		}
282		break;
283	}
284
285	return (result);
286}
287.Ed
288.Pp
289There are two main issues, however, with that listener, that you should be
290aware of when approaching to write your own security model:
291.Bl -enum -offset indent
292.It
293.Xr kauth 9
294uses restrictive decisions: if you attach this listener on-top of an existing
295security model, even if it would allow the request, it could still be denied.
296.It
297If you attach this listener as the only listener for the network scope,
298there are many other requests that will be deferred and, eventually,
299denied \(em which may not be desired.
300.El
301.Pp
302That's why before implementing listeners, it should be clear whether they
303implement an entirely new from scratch security model, or add on-top of an
304existing one.
305.Sh PROGRAMMING CONSIDERATIONS
306There are several things you should remember when writing a security model:
307.Bl -dash -offset indent
308.It
309Pay attention to the correctness of your
310.Nm
311implementation of the desired policy.
312Certain rights can grant more privileges on the system than others,
313like allowing calls to
314.Xr chroot 2
315or mounting a file-system.
316.It
317All unhandled requests are denied by default.
318.It
319Authorization requests can not be issued when the kernel is holding any
320locks.
321This is a requirement from kernel code to allow designing security models
322where the request should be dispatched to userspace or a different host.
323.It
324Private listener data \(em such as internal data structures \(em is
325entirely under the responsibility of the developer.
326Locking, synchronization, and garbage collection are all things that
327.Xr kauth 9
328does
329.Em not
330take care of for you!
331.El
332.Ss STACKING ON AN EXISTING SECURITY MODEL
333One of the shortcomings of
334.Xr kauth 9
335is that it does not provide any stacking mechanism, similar to Linux Security
336Modules (LSM).
337This, however, is considered a feature in reducing dependency on other people's
338code.
339.Pp
340To properly "stack" minor adjustments on-top of an existing security model,
341one could use one of two approaches:
342.Bl -enum
343.It
344Register an internal scope for the security model to be used as a
345fall-back when requests are deferred.
346.Pp
347This requires the security model developer to add an internal scope for
348every scope the model partly covers, and register the fall-back
349listeners to it.
350In the model's listener(s) for the scope, when a defer decision is made, the
351request is passed to be authorized on the internal scope, effectively using
352the fall-back security model.
353.Pp
354Here is example code that implements the above:
355.Bd -literal
356#include <secmodel/bsd44/bsd44.h>
357
358/*
359 * Internal fall-back scope for the network scope.
360 */
361#define	JENNA_ISCOPE_NETWORK "jenna.iscope.network"
362static kauth_scope_t secmodel_jenna_iscope_network;
363
364/*
365 * Jenna's entry point. Register internal scope for the network scope
366 * which we partly cover for fall-back authorization.
367 */
368void
369secmodel_jenna_start(void)
370{
371	secmodel_jenna_iscope_network = kauth_register_scope(
372	    JENNA_ISCOPE_NETWORK, NULL, NULL);
373
374	kauth_listen_scope(JENNA_ISCOPE_NETWORK,
375	    secmodel_bsd44_suser_network_cb, NULL);
376	kauth_listen_scope(JENNA_ISCOPE_NETWORK,
377	    secmodel_securelevel_network_cb, NULL);
378}
379
380/*
381 * Jenna sits on top of another model, effectively filtering requests.
382 * If it has nothing to say, it discards the request. This is a good
383 * example for fine-tuning a security model for a special need.
384 */
385int
386secmodel_jenna_network_cb(kauth_cred_t cred, kauth_action_t action,
387    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
388{
389	int result;
390
391	/* Default defer. */
392	result = KAUTH_RESULT_DEFER;
393
394	switch (action) {
395	case KAUTH_NETWORK_BIND:
396		/*
397		 * We only care about bind(2) requests to privileged
398		 * ports.
399		 */
400		if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
401			if (kauth_cred_geteuid(cred) < 1000)
402				result = KAUTH_RESULT_ALLOW;
403		}
404		break;
405	}
406
407	/*
408	 * If we have don't have a decision, fall-back to the bsd44
409	 * security model.
410	 */
411	if (result == KAUTH_RESULT_DEFER)
412		result = kauth_authorize_action(
413		    secmodel_jenna_iscope_network, cred, action,
414		    arg0, arg1, arg2, arg3);
415
416	return (result);
417}
418.Ed
419.It
420If the above is not desired, or cannot be used for any reason, there is
421always the ability to manually call the fall-back routine:
422.Bd -literal
423int
424secmodel_jenna_network_cb(kauth_cred_t cred, kauth_action_t action,
425    void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
426{
427	int result;
428
429	/* Default defer. */
430	result = KAUTH_RESULT_DEFER;
431
432	switch (action) {
433	case KAUTH_NETWORK_BIND:
434		/*
435		 * We only care about bind(2) requests to privileged
436		 * ports.
437		 */
438		if ((u_long)arg0 == KAUTH_REQ_NETWORK_BIND_PRIVPORT) {
439			if (kauth_cred_geteuid(cred) < 1000)
440				result = KAUTH_RESULT_ALLOW;
441		}
442		break;
443	}
444
445	/*
446	 * If we have don't have a decision, fall-back to the bsd44
447	 * security model's suser behavior.
448	 */
449	if (result == KAUTH_RESULT_DEFER)
450		result = secmodel_bsd44_suser_network_cb(cred, action,
451		    cookie, arg0, arg1, arg2, arg3);
452
453	return (result);
454}
455.Ed
456.El
457.Sh AVAILABLE SECURITY MODELS
458The following is a list of security models available in the default
459.Nx
460distribution.
461.Bl -tag -width xxxxxxxx
462.It Xr secmodel_suser 9
463Implements the
464.Em super-user
465(root) security policy.
466.It Xr secmodel_securelevel 9
467Implements the
468.Em securelevel
469security model.
470.It Xr secmodel_extensions 9
471Implements extensions to the traditional
472.Bx 4.4
473security model, like usermounts.
474.It Xr secmodel_bsd44 9
475Traditional
476.Nx
477security model, derived from
478.Bx 4.4 .
479.It Xr secmodel_overlay 9
480Sample overlay security model, sitting on-top of
481.Xr secmodel_bsd44 9 .
482.El
483.Sh CODE REFERENCES
484The core of the
485.Nm
486implementation is in
487.Pa sys/secmodel/secmodel.c .
488.Pp
489The header file
490.In secmodel/secmodel.h
491describes the public interface.
492.Pp
493To make it easier on developers to write new security models from scratch,
494.Nx
495maintains an example
496.Nm
497under
498.Pa share/examples/secmodel/ .
499.Sh SEE ALSO
500.Xr kauth 9 ,
501.Xr module 9 ,
502.Xr secmodel_bsd44 9 ,
503.Xr secmodel_extensions 9 ,
504.Xr secmodel_overlay 9 ,
505.Xr secmodel_securelevel 9 ,
506.Xr secmodel_suser 9
507.Sh HISTORY
508Kernel Authorization was introduced in
509.Nx 4.0
510as the subsystem responsible for authorization and
511credential management.
512Before its introduction, there were several ways for providing resource access
513control:
514.Bl -dash -offset indent -compact
515.It
516Checking if the user in question is the super-user via
517.Fn suser .
518.It
519Comparing the user-id against hard-coded values, often zero.
520.It
521Checking the system securelevel.
522.El
523.Pp
524The problem with the above is that the interface ("can X do Y?") was
525tightly coupled with the implementation ("is X Z?").
526.Xr kauth 9
527allows separating them, dispatching requests with highly detailed
528context using a consistent and clear KPI.
529.Pp
530The
531.Nm
532framework was extended in
533.Nx 6.0
534to implement
535.Nm
536registration and evaluation procedure calls.
537.Sh AUTHORS
538.An Elad Efrat Aq Mt elad@NetBSD.org
539