The branch main has been updated by allanjude:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=2449b9e5fe565be757a4b29093fd1c9c6ffcf3c9

commit 2449b9e5fe565be757a4b29093fd1c9c6ffcf3c9
Author:     Mitchell Horne <mho...@freebsd.org>
AuthorDate: 2022-07-18 21:23:16 +0000
Commit:     Allan Jude <allanj...@freebsd.org>
CommitDate: 2022-07-18 22:06:13 +0000

    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
---
 sys/conf/files                   |  1 +
 sys/ddb/db_command.c             | 16 ++++++++++
 sys/ddb/ddb.h                    |  3 ++
 sys/kern/subr_kdb.c              | 11 +++++++
 sys/security/mac/mac_framework.h | 10 ++++++
 sys/security/mac/mac_kdb.c       | 69 ++++++++++++++++++++++++++++++++++++++++
 sys/security/mac/mac_policy.h    | 17 ++++++++++
 sys/security/mac_stub/mac_stub.c | 31 ++++++++++++++++++
 sys/security/mac_test/mac_test.c | 39 +++++++++++++++++++++++
 9 files changed, 197 insertions(+)

diff --git a/sys/conf/files b/sys/conf/files
index 30cd9eb7e741..4e1279adc073 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -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
diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c
index 71e9b039d7a9..ab7bec8f2ffc 100644
--- a/sys/ddb/db_command.c
+++ b/sys/ddb/db_command.c
@@ -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.
                 */
diff --git a/sys/ddb/ddb.h b/sys/ddb/ddb.h
index dce4e80ac117..4c8a4f165461 100644
--- a/sys/ddb/ddb.h
+++ b/sys/ddb/ddb.h
@@ -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 */
 };
 
 /*
diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c
index 6aa8bd17e048..b1bf197be3dc 100644
--- a/sys/kern/subr_kdb.c
+++ b/sys/kern/subr_kdb.c
@@ -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;
diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h
index 7a46fbedb28d..78a991fe10fe 100644
--- a/sys/security/mac/mac_framework.h
+++ b/sys/security/mac/mac_framework.h
@@ -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);
diff --git a/sys/security/mac/mac_kdb.c b/sys/security/mac/mac_kdb.c
new file mode 100644
index 000000000000..9082ec7d4580
--- /dev/null
+++ b/sys/security/mac/mac_kdb.c
@@ -0,0 +1,69 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2021-2022 Klara Systems
+ *
+ * This software was developed by Mitchell Horne <mho...@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);
+}
diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h
index b875e6eb5487..97b3522abf51 100644
--- a/sys/security/mac/mac_policy.h
+++ b/sys/security/mac/mac_policy.h
@@ -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;
diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c
index 8174345f073a..6b32408b92fe 100644
--- a/sys/security/mac_stub/mac_stub.c
+++ b/sys/security/mac_stub/mac_stub.c
@@ -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,
diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c
index 12291fbd37d9..48c8fe782909 100644
--- a/sys/security/mac_test/mac_test.c
+++ b/sys/security/mac_test/mac_test.c
@@ -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,

Reply via email to