mac: kdb/ddb framework hooks
Add three simple hooks to the debugger allowing for a loaded MAC policy to intervene if desired: 1. Before invoking the kdb backend 2. Before ddb command registration 3. Before ddb command execution We extend struct db_command with a private pointer and two flag bits reserved for policy use. Reviewed by: markj Sponsored by: Juniper Networks, Inc. Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D35370
This commit is contained in:
parent
a305b20ead
commit
2449b9e5fe
@ -5118,6 +5118,7 @@ security/audit/bsm_socket_type.c optional audit
|
||||
security/audit/bsm_token.c optional audit
|
||||
security/mac/mac_audit.c optional mac audit
|
||||
security/mac/mac_cred.c optional mac
|
||||
security/mac/mac_kdb.c optional mac
|
||||
security/mac/mac_framework.c optional mac
|
||||
security/mac/mac_inet.c optional mac inet | mac inet6
|
||||
security/mac/mac_inet6.c optional mac inet6
|
||||
|
@ -59,6 +59,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/setjmp.h>
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
|
||||
/*
|
||||
* Exported global variables
|
||||
*/
|
||||
@ -236,6 +238,13 @@ db_command_register(struct db_command_table *list, struct db_command *cmd)
|
||||
{
|
||||
struct db_command *c, *last;
|
||||
|
||||
#ifdef MAC
|
||||
if (mac_ddb_command_register(list, cmd)) {
|
||||
printf("%s: MAC policy refused registration of command %s\n",
|
||||
__func__, cmd->name);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
last = NULL;
|
||||
LIST_FOREACH(c, list, next) {
|
||||
int n = strcmp(cmd->name, c->name);
|
||||
@ -480,6 +489,13 @@ db_command(struct db_command **last_cmdp, struct db_command_table *cmd_table,
|
||||
|
||||
*last_cmdp = cmd;
|
||||
if (cmd != NULL) {
|
||||
#ifdef MAC
|
||||
if (mac_ddb_command_exec(cmd, addr, have_addr, count, modif)) {
|
||||
db_printf("MAC prevented execution of command %s\n",
|
||||
cmd->name);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* Execute the command.
|
||||
*/
|
||||
|
@ -119,8 +119,11 @@ struct db_command {
|
||||
#define CS_SET_DOT 0x100 /* set dot after command */
|
||||
#define DB_CMD_MEMSAFE 0x1000 /* Command does not allow reads or writes to
|
||||
* arbitrary memory. */
|
||||
#define DB_MAC1 0x10000 /* For MAC policy use */
|
||||
#define DB_MAC2 0x20000
|
||||
struct db_command_table *more; /* another level of command */
|
||||
LIST_ENTRY(db_command) next; /* next entry in the command table */
|
||||
void *mac_priv; /* For MAC policy use */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -53,6 +53,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/smp.h>
|
||||
#endif
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
|
||||
u_char __read_frequently kdb_active = 0;
|
||||
static void *kdb_jmpbufp = NULL;
|
||||
struct kdb_dbbe *kdb_dbbe = NULL;
|
||||
@ -731,6 +733,15 @@ kdb_trap(int type, int code, struct trapframe *tf)
|
||||
cngrab();
|
||||
|
||||
for (;;) {
|
||||
#ifdef MAC
|
||||
if (mac_kdb_check_backend(be) != 0) {
|
||||
printf("MAC prevented execution of KDB backend: %s\n",
|
||||
be->dbbe_name);
|
||||
/* Unhandled breakpoint traps are fatal. */
|
||||
handled = 1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
handled = be->dbbe_trap(type, code);
|
||||
if (be == kdb_dbbe)
|
||||
break;
|
||||
|
@ -65,6 +65,7 @@ struct image_params;
|
||||
struct inpcb;
|
||||
struct ip6q;
|
||||
struct ipq;
|
||||
struct kdb_dbbe;
|
||||
struct ksem;
|
||||
struct label;
|
||||
struct m_tag;
|
||||
@ -92,6 +93,8 @@ struct vop_setlabel_args;
|
||||
#include <sys/acl.h> /* XXX acl_type_t */
|
||||
#include <sys/types.h> /* accmode_t */
|
||||
|
||||
#include <ddb/ddb.h> /* db_expr_t */
|
||||
|
||||
/*
|
||||
* Entry points to the TrustedBSD MAC Framework from the remainder of the
|
||||
* kernel: entry points are named based on a principle object type and an
|
||||
@ -130,6 +133,11 @@ void mac_cred_create_swapper(struct ucred *cred);
|
||||
void mac_cred_destroy(struct ucred *);
|
||||
void mac_cred_init(struct ucred *);
|
||||
|
||||
int mac_ddb_command_register(struct db_command_table *table,
|
||||
struct db_command *cmd);
|
||||
int mac_ddb_command_exec(struct db_command *cmd, db_expr_t addr,
|
||||
bool have_addr, db_expr_t count, char *modif);
|
||||
|
||||
void mac_devfs_create_device(struct ucred *cred, struct mount *mp,
|
||||
struct cdev *dev, struct devfs_dirent *de);
|
||||
void mac_devfs_create_directory(struct mount *mp, char *dirname,
|
||||
@ -205,6 +213,8 @@ int mac_ipq_match(struct mbuf *m, struct ipq *q);
|
||||
void mac_ipq_reassemble(struct ipq *q, struct mbuf *m);
|
||||
void mac_ipq_update(struct mbuf *m, struct ipq *q);
|
||||
|
||||
int mac_kdb_check_backend(struct kdb_dbbe *be);
|
||||
|
||||
int mac_kenv_check_dump(struct ucred *cred);
|
||||
int mac_kenv_check_get(struct ucred *cred, char *name);
|
||||
int mac_kenv_check_set(struct ucred *cred, char *name, char *value);
|
||||
|
69
sys/security/mac/mac_kdb.c
Normal file
69
sys/security/mac/mac_kdb.c
Normal file
@ -0,0 +1,69 @@
|
||||
/*-
|
||||
* 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 "opt_mac.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <ddb/ddb.h>
|
||||
|
||||
#include <security/mac/mac_framework.h>
|
||||
#include <security/mac/mac_internal.h>
|
||||
#include <security/mac/mac_policy.h>
|
||||
|
||||
int
|
||||
mac_kdb_check_backend(struct kdb_dbbe *be)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
MAC_POLICY_CHECK_NOSLEEP(kdb_check_backend, be);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
mac_ddb_command_register(struct db_command_table *table, struct db_command *cmd)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
MAC_POLICY_CHECK_NOSLEEP(ddb_command_register, table, cmd);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
mac_ddb_command_exec(struct db_command *cmd, db_expr_t addr,
|
||||
bool have_addr, db_expr_t count, char *modif)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
MAC_POLICY_CHECK_NOSLEEP(ddb_command_exec, cmd, addr, have_addr,
|
||||
count, modif);
|
||||
return (error);
|
||||
}
|
@ -66,18 +66,22 @@
|
||||
#include <sys/acl.h> /* XXX acl_type_t */
|
||||
#include <sys/types.h> /* XXX accmode_t */
|
||||
|
||||
#include <ddb/ddb.h> /* XXX db_expr_t */
|
||||
|
||||
struct acl;
|
||||
struct auditinfo;
|
||||
struct auditinfo_addr;
|
||||
struct bpf_d;
|
||||
struct cdev;
|
||||
struct componentname;
|
||||
struct db_command;
|
||||
struct devfs_dirent;
|
||||
struct ifnet;
|
||||
struct image_params;
|
||||
struct inpcb;
|
||||
struct ip6q;
|
||||
struct ipq;
|
||||
struct kdb_dbbe;
|
||||
struct ksem;
|
||||
struct label;
|
||||
struct mac_policy_conf;
|
||||
@ -168,6 +172,12 @@ typedef int (*mpo_cred_internalize_label_t)(struct label *label,
|
||||
typedef void (*mpo_cred_relabel_t)(struct ucred *cred,
|
||||
struct label *newlabel);
|
||||
|
||||
typedef int (*mpo_ddb_command_register_t)(struct db_command_table *table,
|
||||
struct db_command *cmd);
|
||||
typedef int (*mpo_ddb_command_exec_t)(struct db_command *cmd,
|
||||
db_expr_t addr, bool have_addr, db_expr_t count,
|
||||
char *modif);
|
||||
|
||||
typedef void (*mpo_devfs_create_device_t)(struct ucred *cred,
|
||||
struct mount *mp, struct cdev *dev,
|
||||
struct devfs_dirent *de, struct label *delabel);
|
||||
@ -249,6 +259,8 @@ typedef void (*mpo_ipq_reassemble)(struct ipq *q, struct label *qlabel,
|
||||
typedef void (*mpo_ipq_update_t)(struct mbuf *m, struct label *mlabel,
|
||||
struct ipq *q, struct label *qlabel);
|
||||
|
||||
typedef int (*mpo_kdb_check_backend_t)(struct kdb_dbbe *be);
|
||||
|
||||
typedef int (*mpo_kenv_check_dump_t)(struct ucred *cred);
|
||||
typedef int (*mpo_kenv_check_get_t)(struct ucred *cred, char *name);
|
||||
typedef int (*mpo_kenv_check_set_t)(struct ucred *cred, char *name,
|
||||
@ -720,6 +732,9 @@ struct mac_policy_ops {
|
||||
mpo_cred_internalize_label_t mpo_cred_internalize_label;
|
||||
mpo_cred_relabel_t mpo_cred_relabel;
|
||||
|
||||
mpo_ddb_command_register_t mpo_ddb_command_register;
|
||||
mpo_ddb_command_exec_t mpo_ddb_command_exec;
|
||||
|
||||
mpo_devfs_create_device_t mpo_devfs_create_device;
|
||||
mpo_devfs_create_directory_t mpo_devfs_create_directory;
|
||||
mpo_devfs_create_symlink_t mpo_devfs_create_symlink;
|
||||
@ -761,6 +776,8 @@ struct mac_policy_ops {
|
||||
mpo_ipq_reassemble mpo_ipq_reassemble;
|
||||
mpo_ipq_update_t mpo_ipq_update;
|
||||
|
||||
mpo_kdb_check_backend_t mpo_kdb_check_backend;
|
||||
|
||||
mpo_kenv_check_dump_t mpo_kenv_check_dump;
|
||||
mpo_kenv_check_get_t mpo_kenv_check_get;
|
||||
mpo_kenv_check_set_t mpo_kenv_check_set;
|
||||
|
@ -54,6 +54,7 @@
|
||||
#include <sys/acl.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/extattr.h>
|
||||
#include <sys/kdb.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/ksem.h>
|
||||
#include <sys/mount.h>
|
||||
@ -72,6 +73,8 @@
|
||||
#include <sys/sem.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
#include <ddb/ddb.h>
|
||||
|
||||
#include <fs/devfs/devfs.h>
|
||||
|
||||
#include <net/bpfdesc.h>
|
||||
@ -314,6 +317,22 @@ stub_cred_relabel(struct ucred *cred, struct label *newlabel)
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
stub_ddb_command_exec(struct db_command *cmd, db_expr_t addr, bool have_addr,
|
||||
db_expr_t count, char *modif)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
stub_ddb_command_register(struct db_command_table *table,
|
||||
struct db_command *cmd)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
stub_devfs_create_device(struct ucred *cred, struct mount *mp,
|
||||
struct cdev *dev, struct devfs_dirent *de, struct label *delabel)
|
||||
@ -476,6 +495,13 @@ stub_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q,
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
stub_kdb_check_backend(struct kdb_dbbe *be)
|
||||
{
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
stub_kenv_check_dump(struct ucred *cred)
|
||||
{
|
||||
@ -1685,6 +1711,9 @@ static struct mac_policy_ops stub_ops =
|
||||
.mpo_cred_internalize_label = stub_internalize_label,
|
||||
.mpo_cred_relabel= stub_cred_relabel,
|
||||
|
||||
.mpo_ddb_command_exec = stub_ddb_command_exec,
|
||||
.mpo_ddb_command_register = stub_ddb_command_register,
|
||||
|
||||
.mpo_devfs_create_device = stub_devfs_create_device,
|
||||
.mpo_devfs_create_directory = stub_devfs_create_directory,
|
||||
.mpo_devfs_create_symlink = stub_devfs_create_symlink,
|
||||
@ -1726,6 +1755,8 @@ static struct mac_policy_ops stub_ops =
|
||||
.mpo_ipq_update = stub_ipq_update,
|
||||
.mpo_ipq_reassemble = stub_ipq_reassemble,
|
||||
|
||||
.mpo_kdb_check_backend = stub_kdb_check_backend,
|
||||
|
||||
.mpo_kenv_check_dump = stub_kenv_check_dump,
|
||||
.mpo_kenv_check_get = stub_kenv_check_get,
|
||||
.mpo_kenv_check_set = stub_kenv_check_set,
|
||||
|
@ -69,6 +69,8 @@
|
||||
#include <sys/sx.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <ddb/ddb.h>
|
||||
|
||||
#include <fs/devfs/devfs.h>
|
||||
|
||||
#include <net/bpfdesc.h>
|
||||
@ -453,6 +455,28 @@ test_cred_relabel(struct ucred *cred, struct label *newlabel)
|
||||
COUNTER_INC(cred_relabel);
|
||||
}
|
||||
|
||||
COUNTER_DECL(ddb_command_exec);
|
||||
static int
|
||||
test_ddb_command_exec(struct db_command *cmd, db_expr_t addr, bool have_addr,
|
||||
db_expr_t count, char *modif)
|
||||
{
|
||||
|
||||
COUNTER_INC(ddb_command_exec);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
COUNTER_DECL(ddb_command_register);
|
||||
static int
|
||||
test_ddb_command_register(struct db_command_table *table,
|
||||
struct db_command *cmd)
|
||||
{
|
||||
|
||||
COUNTER_INC(ddb_command_register);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
COUNTER_DECL(devfs_create_device);
|
||||
static void
|
||||
test_devfs_create_device(struct ucred *cred, struct mount *mp,
|
||||
@ -868,6 +892,16 @@ test_ipq_update(struct mbuf *m, struct label *mlabel, struct ipq *q,
|
||||
COUNTER_INC(ipq_update);
|
||||
}
|
||||
|
||||
COUNTER_DECL(kdb_backend_check);
|
||||
static int
|
||||
test_kdb_check_backend(struct kdb_dbbe *be)
|
||||
{
|
||||
|
||||
COUNTER_INC(kdb_backend_check);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
COUNTER_DECL(kenv_check_dump);
|
||||
static int
|
||||
test_kenv_check_dump(struct ucred *cred)
|
||||
@ -3022,6 +3056,9 @@ static struct mac_policy_ops test_ops =
|
||||
.mpo_cred_internalize_label = test_cred_internalize_label,
|
||||
.mpo_cred_relabel = test_cred_relabel,
|
||||
|
||||
.mpo_ddb_command_exec = test_ddb_command_exec,
|
||||
.mpo_ddb_command_register = test_ddb_command_register,
|
||||
|
||||
.mpo_devfs_create_device = test_devfs_create_device,
|
||||
.mpo_devfs_create_directory = test_devfs_create_directory,
|
||||
.mpo_devfs_create_symlink = test_devfs_create_symlink,
|
||||
@ -3078,6 +3115,8 @@ static struct mac_policy_ops test_ops =
|
||||
.mpo_ipq_reassemble = test_ipq_reassemble,
|
||||
.mpo_ipq_update = test_ipq_update,
|
||||
|
||||
.mpo_kdb_check_backend = test_kdb_check_backend,
|
||||
|
||||
.mpo_kenv_check_dump = test_kenv_check_dump,
|
||||
.mpo_kenv_check_get = test_kenv_check_get,
|
||||
.mpo_kenv_check_set = test_kenv_check_set,
|
||||
|
Loading…
Reference in New Issue
Block a user