mac: add new mac_ddb(4) policy
Generally, access to the kernel debugger is considered to be unsafe from a security perspective since it presents an unrestricted interface to inspect or modify the system state, including sensitive data such as signing keys. However, having some access to debugger functionality on production systems may be useful in determining the cause of a panic or hang. Therefore, it is desirable to have an optional policy which allows limited use of ddb(4) while disabling the functionality which could reveal system secrets. This loadable MAC module allows for the use of some ddb(4) commands while preventing the execution of others. The commands have been broadly grouped into three categories: - Those which are 'safe' and will not emit sensitive data (e.g. trace). Generally, these commands are deterministic and don't accept arguments. - Those which are definitively unsafe (e.g. examine <addr>, search <addr> <value>) - Commands which may be safe to execute depending on the arguments provided (e.g. show thread <addr>). Safe commands have been flagged as such with the DB_CMD_MEMSAFE flag. Commands requiring extra validation can provide a function to do so. For example, 'show thread <addr>' can be used as long as addr can be checked against the system's list of process structures. The policy also prevents debugger backends other than ddb(4) from executing, for example gdb(4). Reviewed by: markj, pauamma_gundo.com (manpages) Sponsored by: Juniper Networks, Inc. Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D35371
This commit is contained in:
parent
2449b9e5fe
commit
287d467c5d
@ -150,6 +150,7 @@ and
|
|||||||
manual pages.
|
manual pages.
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr ddb 4 ,
|
.Xr ddb 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr textdump 4 ,
|
.Xr textdump 4 ,
|
||||||
.Xr sysctl 8
|
.Xr sysctl 8
|
||||||
.Sh HISTORY
|
.Sh HISTORY
|
||||||
|
@ -1602,6 +1602,7 @@ directory.
|
|||||||
.Xr kgdb 1 ,
|
.Xr kgdb 1 ,
|
||||||
.Xr acpi 4 ,
|
.Xr acpi 4 ,
|
||||||
.Xr CAM 4 ,
|
.Xr CAM 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_test 4 ,
|
.Xr mac_test 4 ,
|
||||||
.Xr netgraph 4 ,
|
.Xr netgraph 4 ,
|
||||||
.Xr textdump 4 ,
|
.Xr textdump 4 ,
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.\" $FreeBSD$
|
.\" $FreeBSD$
|
||||||
.\"
|
.\"
|
||||||
.Dd May 20, 2021
|
.Dd June 29, 2022
|
||||||
.Dt MAC 4
|
.Dt MAC 4
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -51,10 +51,11 @@ security provisions such as file permissions and superuser checks.
|
|||||||
.Pp
|
.Pp
|
||||||
Currently, the following MAC policy modules are shipped with
|
Currently, the following MAC policy modules are shipped with
|
||||||
.Fx :
|
.Fx :
|
||||||
.Bl -column ".Xr mac_seeotheruids 4" "low-watermark mac policy" ".Em Labeling" "boot only"
|
.Bl -column ".Xr mac_seeotheruids 4" "ddb(4) interface restrictions" ".Em Labeling" "boot only"
|
||||||
.It Sy Name Ta Sy Description Ta Sy Labeling Ta Sy "Load time"
|
.It Sy Name Ta Sy Description Ta Sy Labeling Ta Sy "Load time"
|
||||||
.It Xr mac_biba 4 Ta "Biba integrity policy" Ta yes Ta boot only
|
.It Xr mac_biba 4 Ta "Biba integrity policy" Ta yes Ta boot only
|
||||||
.It Xr mac_bsdextended 4 Ta "File system firewall" Ta no Ta any time
|
.It Xr mac_bsdextended 4 Ta "File system firewall" Ta no Ta any time
|
||||||
|
.It Xr mac_ddb 4 Ta "ddb(4) interface restrictions" Ta no Ta any time
|
||||||
.It Xr mac_ifoff 4 Ta "Interface silencing" Ta no Ta any time
|
.It Xr mac_ifoff 4 Ta "Interface silencing" Ta no Ta any time
|
||||||
.It Xr mac_lomac 4 Ta "Low-Watermark MAC policy" Ta yes Ta boot only
|
.It Xr mac_lomac 4 Ta "Low-Watermark MAC policy" Ta yes Ta boot only
|
||||||
.It Xr mac_mls 4 Ta "Confidentiality policy" Ta yes Ta boot only
|
.It Xr mac_mls 4 Ta "Confidentiality policy" Ta yes Ta boot only
|
||||||
@ -201,6 +202,7 @@ man page.
|
|||||||
.Xr mac 3 ,
|
.Xr mac 3 ,
|
||||||
.Xr mac_biba 4 ,
|
.Xr mac_biba 4 ,
|
||||||
.Xr mac_bsdextended 4 ,
|
.Xr mac_bsdextended 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_ifoff 4 ,
|
.Xr mac_ifoff 4 ,
|
||||||
.Xr mac_lomac 4 ,
|
.Xr mac_lomac 4 ,
|
||||||
.Xr mac_mls 4 ,
|
.Xr mac_mls 4 ,
|
||||||
|
@ -117,6 +117,7 @@ Currently does nothing interesting.
|
|||||||
.Xr syslog 3 ,
|
.Xr syslog 3 ,
|
||||||
.Xr mac 4 ,
|
.Xr mac 4 ,
|
||||||
.Xr mac_biba 4 ,
|
.Xr mac_biba 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_ifoff 4 ,
|
.Xr mac_ifoff 4 ,
|
||||||
.Xr mac_lomac 4 ,
|
.Xr mac_lomac 4 ,
|
||||||
.Xr mac_mls 4 ,
|
.Xr mac_mls 4 ,
|
||||||
|
108
share/man/man4/mac_ddb.4
Normal file
108
share/man/man4/mac_ddb.4
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
.\" Copyright (c) 2022 Klara Systems
|
||||||
|
.\"
|
||||||
|
.\" This software was developed by Mitchell Horne <mhorne@FreeBSD.org>
|
||||||
|
.\" under sponsorship from Juniper Networks and Klara Systems.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
|
||||||
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
.\" SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.Dd June 29, 2022
|
||||||
|
.Dt MAC_DDB 4
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm mac_ddb
|
||||||
|
.Nd "Restricted kernel debugger interface policy"
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
To compile the ddb policy
|
||||||
|
into your kernel, place the following lines in your kernel
|
||||||
|
configuration file:
|
||||||
|
.Bd -ragged -offset indent
|
||||||
|
.Cd "options MAC"
|
||||||
|
.Cd "options MAC_DDB"
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
Alternately, to load the ddb module at boot time, place the following line
|
||||||
|
in your kernel configuration file:
|
||||||
|
.Bd -ragged -offset indent
|
||||||
|
.Cd "options MAC"
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
and in
|
||||||
|
.Xr loader.conf 5 :
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
mac_ddb_load="YES"
|
||||||
|
.Ed
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
policy module implements a MAC policy which restricts the set of commands that
|
||||||
|
can be used at the
|
||||||
|
.Xr ddb 4
|
||||||
|
command prompt.
|
||||||
|
The subset of permitted commands is limited to those which do not read or write
|
||||||
|
to arbitrary memory locations.
|
||||||
|
This is done to deter the possible extraction of system secrets while still
|
||||||
|
allowing enough debugger functionality to diagnose a kernel panic.
|
||||||
|
For example, the
|
||||||
|
.Ic trace
|
||||||
|
or
|
||||||
|
.Ic show registers
|
||||||
|
commands are allowed by this policy, but
|
||||||
|
.Ic show Cm buffer Ar addr
|
||||||
|
is not.
|
||||||
|
.Pp
|
||||||
|
All debugger commands that are declared with the
|
||||||
|
.Va DB_CMD_MEMSAFE
|
||||||
|
flag are allowed by
|
||||||
|
.Nm .
|
||||||
|
The policy provides validation functions to conditionally allow some additional
|
||||||
|
commands, based on the user provided arguments.
|
||||||
|
.Pp
|
||||||
|
When loaded, the
|
||||||
|
.Nm
|
||||||
|
policy also ensures that only the
|
||||||
|
.Xr ddb 4
|
||||||
|
debugger backend may be executed;
|
||||||
|
.Xr gdb 4
|
||||||
|
may not.
|
||||||
|
.Ss Label Format
|
||||||
|
No labels are defined for
|
||||||
|
.Nm .
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr ddb 4 ,
|
||||||
|
.Xr mac 4 ,
|
||||||
|
.Xr mac_biba 4 ,
|
||||||
|
.Xr mac_bsdextended 4 ,
|
||||||
|
.Xr mac_ifoff 4 ,
|
||||||
|
.Xr mac_lomac 4 ,
|
||||||
|
.Xr mac_mls 4 ,
|
||||||
|
.Xr mac_none 4 ,
|
||||||
|
.Xr mac_partition 4 ,
|
||||||
|
.Xr mac_portacl 4 ,
|
||||||
|
.Xr mac_seeotheruids 4 ,
|
||||||
|
.Xr mac_test 4 ,
|
||||||
|
.Xr mac 9
|
||||||
|
.Sh BUGS
|
||||||
|
While the MAC Framework design is intended to support the containment of
|
||||||
|
the root user, not all attack channels are currently protected by entry
|
||||||
|
point checks.
|
||||||
|
As such, MAC Framework policies should not be relied on, in isolation,
|
||||||
|
to protect against a malicious privileged user.
|
@ -194,6 +194,7 @@ man pages.
|
|||||||
.Xr mac 4 ,
|
.Xr mac 4 ,
|
||||||
.Xr mac_biba 4 ,
|
.Xr mac_biba 4 ,
|
||||||
.Xr mac_bsdextended 4 ,
|
.Xr mac_bsdextended 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_ifoff 4 ,
|
.Xr mac_ifoff 4 ,
|
||||||
.Xr mac_mls 4 ,
|
.Xr mac_mls 4 ,
|
||||||
.Xr mac_none 4 ,
|
.Xr mac_none 4 ,
|
||||||
|
@ -210,6 +210,7 @@ allow the superuser to bypass MLS protections.
|
|||||||
.Xr mac 4 ,
|
.Xr mac 4 ,
|
||||||
.Xr mac_biba 4 ,
|
.Xr mac_biba 4 ,
|
||||||
.Xr mac_bsdextended 4 ,
|
.Xr mac_bsdextended 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_ifoff 4 ,
|
.Xr mac_ifoff 4 ,
|
||||||
.Xr mac_lomac 4 ,
|
.Xr mac_lomac 4 ,
|
||||||
.Xr mac_none 4 ,
|
.Xr mac_none 4 ,
|
||||||
|
@ -71,6 +71,7 @@ No labels are defined for
|
|||||||
.Xr mac 4 ,
|
.Xr mac 4 ,
|
||||||
.Xr mac_biba 4 ,
|
.Xr mac_biba 4 ,
|
||||||
.Xr mac_bsdextended 4 ,
|
.Xr mac_bsdextended 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_ifoff 4 ,
|
.Xr mac_ifoff 4 ,
|
||||||
.Xr mac_lomac 4 ,
|
.Xr mac_lomac 4 ,
|
||||||
.Xr mac_mls 4 ,
|
.Xr mac_mls 4 ,
|
||||||
|
@ -91,6 +91,7 @@ partition/none
|
|||||||
.Xr mac 4 ,
|
.Xr mac 4 ,
|
||||||
.Xr mac_biba 4 ,
|
.Xr mac_biba 4 ,
|
||||||
.Xr mac_bsdextended 4 ,
|
.Xr mac_bsdextended 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_ifoff 4 ,
|
.Xr mac_ifoff 4 ,
|
||||||
.Xr mac_lomac 4 ,
|
.Xr mac_lomac 4 ,
|
||||||
.Xr mac_mls 4 ,
|
.Xr mac_mls 4 ,
|
||||||
|
@ -194,6 +194,7 @@ This tunable will exempt port 0 allocation from rule checking.
|
|||||||
.Xr ip 4 ,
|
.Xr ip 4 ,
|
||||||
.Xr mac_biba 4 ,
|
.Xr mac_biba 4 ,
|
||||||
.Xr mac_bsdextended 4 ,
|
.Xr mac_bsdextended 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_ifoff 4 ,
|
.Xr mac_ifoff 4 ,
|
||||||
.Xr mac_mls 4 ,
|
.Xr mac_mls 4 ,
|
||||||
.Xr mac_none 4 ,
|
.Xr mac_none 4 ,
|
||||||
|
@ -90,6 +90,7 @@ No labels are defined for
|
|||||||
.Xr mac 4 ,
|
.Xr mac 4 ,
|
||||||
.Xr mac_biba 4 ,
|
.Xr mac_biba 4 ,
|
||||||
.Xr mac_bsdextended 4 ,
|
.Xr mac_bsdextended 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_ifoff 4 ,
|
.Xr mac_ifoff 4 ,
|
||||||
.Xr mac_lomac 4 ,
|
.Xr mac_lomac 4 ,
|
||||||
.Xr mac_mls 4 ,
|
.Xr mac_mls 4 ,
|
||||||
|
@ -74,6 +74,7 @@ No labels are defined for
|
|||||||
.Xr mac 4 ,
|
.Xr mac 4 ,
|
||||||
.Xr mac_biba 4 ,
|
.Xr mac_biba 4 ,
|
||||||
.Xr mac_bsdextended 4 ,
|
.Xr mac_bsdextended 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_ifoff 4 ,
|
.Xr mac_ifoff 4 ,
|
||||||
.Xr mac_lomac 4 ,
|
.Xr mac_lomac 4 ,
|
||||||
.Xr mac_mls 4 ,
|
.Xr mac_mls 4 ,
|
||||||
|
@ -76,6 +76,7 @@ No labels are defined for
|
|||||||
.Xr mac 4 ,
|
.Xr mac 4 ,
|
||||||
.Xr mac_biba 4 ,
|
.Xr mac_biba 4 ,
|
||||||
.Xr mac_bsdextended 4 ,
|
.Xr mac_bsdextended 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_ifoff 4 ,
|
.Xr mac_ifoff 4 ,
|
||||||
.Xr mac_lomac 4 ,
|
.Xr mac_lomac 4 ,
|
||||||
.Xr mac_mls 4 ,
|
.Xr mac_mls 4 ,
|
||||||
|
@ -152,6 +152,7 @@ for information on the MAC Framework APIs.
|
|||||||
.Xr posix1e 3 ,
|
.Xr posix1e 3 ,
|
||||||
.Xr mac_biba 4 ,
|
.Xr mac_biba 4 ,
|
||||||
.Xr mac_bsdextended 4 ,
|
.Xr mac_bsdextended 4 ,
|
||||||
|
.Xr mac_ddb 4 ,
|
||||||
.Xr mac_ifoff 4 ,
|
.Xr mac_ifoff 4 ,
|
||||||
.Xr mac_lomac 4 ,
|
.Xr mac_lomac 4 ,
|
||||||
.Xr mac_mls 4 ,
|
.Xr mac_mls 4 ,
|
||||||
|
@ -1235,6 +1235,7 @@ options AUDIT
|
|||||||
options MAC
|
options MAC
|
||||||
options MAC_BIBA
|
options MAC_BIBA
|
||||||
options MAC_BSDEXTENDED
|
options MAC_BSDEXTENDED
|
||||||
|
options MAC_DDB
|
||||||
options MAC_IFOFF
|
options MAC_IFOFF
|
||||||
options MAC_LOMAC
|
options MAC_LOMAC
|
||||||
options MAC_MLS
|
options MAC_MLS
|
||||||
|
@ -5137,6 +5137,7 @@ security/mac/mac_sysv_sem.c optional mac
|
|||||||
security/mac/mac_sysv_shm.c optional mac
|
security/mac/mac_sysv_shm.c optional mac
|
||||||
security/mac/mac_vfs.c optional mac
|
security/mac/mac_vfs.c optional mac
|
||||||
security/mac_biba/mac_biba.c optional mac_biba
|
security/mac_biba/mac_biba.c optional mac_biba
|
||||||
|
security/mac_ddb/mac_ddb.c optional mac_ddb
|
||||||
security/mac_bsdextended/mac_bsdextended.c optional mac_bsdextended
|
security/mac_bsdextended/mac_bsdextended.c optional mac_bsdextended
|
||||||
security/mac_bsdextended/ugidfw_system.c optional mac_bsdextended
|
security/mac_bsdextended/ugidfw_system.c optional mac_bsdextended
|
||||||
security/mac_bsdextended/ugidfw_vnode.c optional mac_bsdextended
|
security/mac_bsdextended/ugidfw_vnode.c optional mac_bsdextended
|
||||||
|
@ -156,6 +156,7 @@ LIBICONV
|
|||||||
MAC opt_global.h
|
MAC opt_global.h
|
||||||
MAC_BIBA opt_dontuse.h
|
MAC_BIBA opt_dontuse.h
|
||||||
MAC_BSDEXTENDED opt_dontuse.h
|
MAC_BSDEXTENDED opt_dontuse.h
|
||||||
|
MAC_DDB opt_dontuse.h
|
||||||
MAC_IFOFF opt_dontuse.h
|
MAC_IFOFF opt_dontuse.h
|
||||||
MAC_LOMAC opt_dontuse.h
|
MAC_LOMAC opt_dontuse.h
|
||||||
MAC_MLS opt_dontuse.h
|
MAC_MLS opt_dontuse.h
|
||||||
|
@ -99,6 +99,7 @@ LIST_HEAD(db_command_table, db_command);
|
|||||||
extern struct db_command_table db_cmd_table;
|
extern struct db_command_table db_cmd_table;
|
||||||
extern struct db_command_table db_show_table;
|
extern struct db_command_table db_show_table;
|
||||||
extern struct db_command_table db_show_all_table;
|
extern struct db_command_table db_show_all_table;
|
||||||
|
extern struct db_command_table db_show_active_table;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Type signature for a function implementing a ddb command.
|
* Type signature for a function implementing a ddb command.
|
||||||
|
@ -219,6 +219,7 @@ SUBDIR= \
|
|||||||
lpt \
|
lpt \
|
||||||
${_mac_biba} \
|
${_mac_biba} \
|
||||||
${_mac_bsdextended} \
|
${_mac_bsdextended} \
|
||||||
|
${_mac_ddb} \
|
||||||
${_mac_ifoff} \
|
${_mac_ifoff} \
|
||||||
${_mac_lomac} \
|
${_mac_lomac} \
|
||||||
${_mac_mls} \
|
${_mac_mls} \
|
||||||
@ -546,6 +547,9 @@ _vmware= vmware
|
|||||||
.if ${KERN_OPTS:MMAC} || defined(ALL_MODULES)
|
.if ${KERN_OPTS:MMAC} || defined(ALL_MODULES)
|
||||||
_mac_biba= mac_biba
|
_mac_biba= mac_biba
|
||||||
_mac_bsdextended= mac_bsdextended
|
_mac_bsdextended= mac_bsdextended
|
||||||
|
.if ${KERN_OPTS:MDDB} || defined(ALL_MODULES)
|
||||||
|
_mac_ddb= mac_ddb
|
||||||
|
.endif
|
||||||
_mac_ifoff= mac_ifoff
|
_mac_ifoff= mac_ifoff
|
||||||
_mac_lomac= mac_lomac
|
_mac_lomac= mac_lomac
|
||||||
_mac_mls= mac_mls
|
_mac_mls= mac_mls
|
||||||
|
6
sys/modules/mac_ddb/Makefile
Normal file
6
sys/modules/mac_ddb/Makefile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.PATH: ${SRCTOP}/sys/security/mac_ddb
|
||||||
|
|
||||||
|
KMOD= mac_ddb
|
||||||
|
SRCS= mac_ddb.c
|
||||||
|
|
||||||
|
.include <bsd.kmod.mk>
|
266
sys/security/mac_ddb/mac_ddb.c
Normal file
266
sys/security/mac_ddb/mac_ddb.c
Normal file
@ -0,0 +1,266 @@
|
|||||||
|
/*-
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021-2022 Klara Systems
|
||||||
|
*
|
||||||
|
* This software was developed by Mitchell Horne <mhorne@FreeBSD.org>
|
||||||
|
* under sponsorship from Juniper Networks and Klara Systems.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/kdb.h>
|
||||||
|
#include <sys/module.h>
|
||||||
|
#include <sys/proc.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
|
#include <ddb/ddb.h>
|
||||||
|
#include <ddb/db_command.h>
|
||||||
|
|
||||||
|
#include <security/mac/mac_policy.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This module provides a limited interface to the ddb(4) kernel debugger. The
|
||||||
|
* intent is to allow execution of useful debugging commands while disallowing
|
||||||
|
* the execution of commands which may be used to inspect/modify arbitrary
|
||||||
|
* system memory.
|
||||||
|
*
|
||||||
|
* Commands which are deterministic in their output or effect and that have
|
||||||
|
* been flagged with DB_CMD_MEMSAFE in their definition will be allowed.
|
||||||
|
*
|
||||||
|
* Other commands are valid within this context so long as there is some
|
||||||
|
* constraint placed on their input arguments. This applies to most 'show'
|
||||||
|
* commands which accept an arbitrary address. If the provided address can be
|
||||||
|
* validated as a real instance of the object (e.g. the 'show proc' address
|
||||||
|
* points to a real struct proc in the process list), then the command may be
|
||||||
|
* executed. This module defines several validation functions which are used to
|
||||||
|
* conditionally allow or block the execution of some commands. For these
|
||||||
|
* commands we define and apply the DB_CMD_VALIDATE flag.
|
||||||
|
*
|
||||||
|
* Any other commands not flagged with DM_CMD_MEMSAFE or DB_CMD_VALIDATE are
|
||||||
|
* considered unsafe for execution.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DB_CMD_VALIDATE DB_MAC1
|
||||||
|
|
||||||
|
typedef int db_validation_fn_t(db_expr_t addr, bool have_addr, db_expr_t count,
|
||||||
|
char *modif);
|
||||||
|
|
||||||
|
static db_validation_fn_t db_thread_valid;
|
||||||
|
|
||||||
|
struct cmd_list_item {
|
||||||
|
const char *name;
|
||||||
|
db_validation_fn_t *validate_fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* List of top-level ddb(4) commands which are allowed by this policy. */
|
||||||
|
static const struct cmd_list_item command_list[] = {
|
||||||
|
{ "thread", db_thread_valid },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* List of ddb(4) 'show' commands which are allowed by this policy. */
|
||||||
|
static const struct cmd_list_item show_command_list[] = {
|
||||||
|
{ "thread", db_thread_valid },
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
db_thread_valid(db_expr_t addr, bool have_addr, db_expr_t count, char *modif)
|
||||||
|
{
|
||||||
|
struct thread *thr;
|
||||||
|
lwpid_t tid;
|
||||||
|
|
||||||
|
/* Default will show the current proc. */
|
||||||
|
if (!have_addr)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/* Validate the provided addr OR tid against the thread list. */
|
||||||
|
tid = db_hex2dec(addr);
|
||||||
|
for (thr = kdb_thr_first(); thr != NULL; thr = kdb_thr_next(thr)) {
|
||||||
|
if ((void *)thr == (void *)addr || tid == thr->td_tid)
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (EACCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
command_match(struct db_command *cmd, struct cmd_list_item item)
|
||||||
|
{
|
||||||
|
db_validation_fn_t *vfn;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = strcmp(cmd->name, item.name);
|
||||||
|
if (n != 0)
|
||||||
|
return (n);
|
||||||
|
|
||||||
|
/* Got an exact match. Update the command struct */
|
||||||
|
vfn = item.validate_fn;
|
||||||
|
if (vfn != NULL) {
|
||||||
|
cmd->flag |= DB_CMD_VALIDATE;
|
||||||
|
cmd->mac_priv = vfn;
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mac_ddb_init(struct mac_policy_conf *conf)
|
||||||
|
{
|
||||||
|
struct db_command *cmd, *prev;
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
/* The command lists are sorted lexographically, as are our arrays. */
|
||||||
|
|
||||||
|
/* Register basic commands. */
|
||||||
|
for (i = 0, cmd = prev = NULL; i < nitems(command_list); i++) {
|
||||||
|
LIST_FOREACH_FROM(cmd, &db_cmd_table, next) {
|
||||||
|
n = command_match(cmd, command_list[i]);
|
||||||
|
if (n == 0) {
|
||||||
|
/* Got an exact match. */
|
||||||
|
prev = cmd;
|
||||||
|
break;
|
||||||
|
} else if (n > 0) {
|
||||||
|
/* Desired command is not registered. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next search begins at the previous match. */
|
||||||
|
cmd = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register 'show' commands which require validation. */
|
||||||
|
for (i = 0, cmd = prev = NULL; i < nitems(show_command_list); i++) {
|
||||||
|
LIST_FOREACH_FROM(cmd, &db_show_table, next) {
|
||||||
|
n = command_match(cmd, show_command_list[i]);
|
||||||
|
if (n == 0) {
|
||||||
|
/* Got an exact match. */
|
||||||
|
prev = cmd;
|
||||||
|
break;
|
||||||
|
} else if (n > 0) {
|
||||||
|
/* Desired command is not registered. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next search begins at the previous match. */
|
||||||
|
cmd = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef INVARIANTS
|
||||||
|
/* Verify the lists are sorted correctly. */
|
||||||
|
const char *a, *b;
|
||||||
|
|
||||||
|
for (i = 0; i < nitems(command_list) - 1; i++) {
|
||||||
|
a = command_list[i].name;
|
||||||
|
b = command_list[i + 1].name;
|
||||||
|
if (strcmp(a, b) > 0)
|
||||||
|
panic("%s: command_list[] not alphabetical: %s,%s",
|
||||||
|
__func__, a, b);
|
||||||
|
}
|
||||||
|
for (i = 0; i < nitems(show_command_list) - 1; i++) {
|
||||||
|
a = show_command_list[i].name;
|
||||||
|
b = show_command_list[i + 1].name;
|
||||||
|
if (strcmp(a, b) > 0)
|
||||||
|
panic("%s: show_command_list[] not alphabetical: %s,%s",
|
||||||
|
__func__, a, b);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mac_ddb_command_register(struct db_command_table *table,
|
||||||
|
struct db_command *cmd)
|
||||||
|
{
|
||||||
|
int i, n;
|
||||||
|
|
||||||
|
if ((cmd->flag & DB_CMD_MEMSAFE) != 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/* For other commands, search the allow-lists. */
|
||||||
|
if (table == &db_show_table) {
|
||||||
|
for (i = 0; i < nitems(show_command_list); i++) {
|
||||||
|
n = command_match(cmd, show_command_list[i]);
|
||||||
|
if (n == 0)
|
||||||
|
/* Got an exact match. */
|
||||||
|
return (0);
|
||||||
|
else if (n > 0)
|
||||||
|
/* Command is not in the policy list. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (table == &db_cmd_table) {
|
||||||
|
for (i = 0; i < nitems(command_list); i++) {
|
||||||
|
n = command_match(cmd, command_list[i]);
|
||||||
|
if (n == 0)
|
||||||
|
/* Got an exact match. */
|
||||||
|
return (0);
|
||||||
|
else if (n > 0)
|
||||||
|
/* Command is not in the policy list. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The command will not be registered. */
|
||||||
|
return (EACCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mac_ddb_command_exec(struct db_command *cmd, db_expr_t addr,
|
||||||
|
bool have_addr, db_expr_t count, char *modif)
|
||||||
|
{
|
||||||
|
db_validation_fn_t *vfn = cmd->mac_priv;
|
||||||
|
|
||||||
|
/* Validate the command and args based on policy. */
|
||||||
|
if ((cmd->flag & DB_CMD_VALIDATE) != 0) {
|
||||||
|
MPASS(vfn != NULL);
|
||||||
|
if (vfn(addr, have_addr, count, modif) == 0)
|
||||||
|
return (0);
|
||||||
|
} else if ((cmd->flag & DB_CMD_MEMSAFE) != 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return (EACCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
mac_ddb_check_backend(struct kdb_dbbe *be)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* Only allow DDB backend to execute. */
|
||||||
|
if (strcmp(be->dbbe_name, "ddb") == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return (EACCES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register functions with MAC Framework policy entry points.
|
||||||
|
*/
|
||||||
|
static struct mac_policy_ops mac_ddb_ops =
|
||||||
|
{
|
||||||
|
.mpo_init = mac_ddb_init,
|
||||||
|
|
||||||
|
.mpo_ddb_command_register = mac_ddb_command_register,
|
||||||
|
.mpo_ddb_command_exec = mac_ddb_command_exec,
|
||||||
|
|
||||||
|
.mpo_kdb_check_backend = mac_ddb_check_backend,
|
||||||
|
};
|
||||||
|
MAC_POLICY_SET(&mac_ddb_ops, mac_ddb, "MAC/DDB", 0, NULL);
|
Loading…
Reference in New Issue
Block a user