From nobody Mon Jul 18 22:06:55 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Lmwzg27L4z1GpWg; Mon, 18 Jul 2022 22:06:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Lmwzg1rgTz3yR7; Mon, 18 Jul 2022 22:06:55 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1658182015; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=XpfCZK0d6eo4ZaOT3dP4xvw7dpD4PMjjRYbXj8P4eLo=; b=jbFxeC2+653aAliHhyZtgDZAOcngC2q/OUv1Ywj+l18/AJIRQnaXJtTkP5uTE5e++geMTZ F1S1uP3k79QrzrZk+iagI7+tM0GATYpb/eEpHmy7tidio2G6fMiOC2iAtKDXWSNaS8FwXX jp7Pr0oAIHrEV2f2EjY8ta/PbA/gNS/UKc4hZkqt0rN8/ee8vliuPoumG8FOlLcBNr0cia /EpK23zXA5nTEpDOtVn00TZMkYOk+K57FRZF3YKIbQkKWLhCxADN7lE6hdXnUTVPrjXnAt 5YlZikPfxLUC/QxF7h2szhHwYKbtTVmTBWwEfuM2aI9I2NwD3EZtGY16voOC3g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Lmwzg0rJhzvM9; Mon, 18 Jul 2022 22:06:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 26IM6teT048190; Mon, 18 Jul 2022 22:06:55 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 26IM6thj048189; Mon, 18 Jul 2022 22:06:55 GMT (envelope-from git) Date: Mon, 18 Jul 2022 22:06:55 GMT Message-Id: <202207182206.26IM6thj048189@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Allan Jude Subject: git: 2449b9e5fe56 - main - mac: kdb/ddb framework hooks List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: allanjude X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 2449b9e5fe565be757a4b29093fd1c9c6ffcf3c9 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1658182015; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=XpfCZK0d6eo4ZaOT3dP4xvw7dpD4PMjjRYbXj8P4eLo=; b=vTyFqsYhGzgd6vyL265ffWLI2oe0SxarBta4nNaQS9FN7HM0ESOu7SEYb0HmZbN83rYNFs 0qLV5EKgkJ1dMPnCf1QmilFY3DyeCvjUT/bozvBrAV9m2bswSorvzA8o6d2SlcCcCrFT4f VDgFWdpBzmJT8D7jnc4+6TWarh8pUdHO6ASvEG8nvuKM5qidmCLPxHNLwIaVfXEsUH/MQ3 9IGHf9AQzU9pzMCMi8qlCQQAyQjIFRGr0ujCUJl7LWWuAtbmN/dTibERaU/mju38CKhqbE m5A0xfh3tgog0fjbe/osiV6WVbqkczaXgBWLlVM86//31IT8Q2LiWEShvjrQ9w== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1658182015; a=rsa-sha256; cv=none; b=RWryuoxaZxILYzXpUUx5619GCVxEuv/lMNEMuNOH4WPRiJHzenU3o+6HmiF4w8h+7sE+G8 W32E2T8Jf2mOI2DCZUo/1do2vacxWxPO2g4TaJTBYS1GQMeDuv0FAuO/irSJbB8JdOeScE SaKBrFHWRRD4RlbQW9WqO91M8kh/X68xH4ZjKR3JJ9Yq8YhjFXnUeR67DHTeMYFdY5E/Sa 2nU/bwM7uQspj+oI7vafJ+6xKNez5nxDgFMbN74+qlZsbrb5yaNjLJ4nAUZfwk9E5qDJY6 WZ3xhIaiz2VtYtY/+mAlYflDeQNi7q7XinQ+PXsdjH2qXe5hwygWgO1RzUUj+Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by allanjude: URL: https://cgit.FreeBSD.org/src/commit/?id=2449b9e5fe565be757a4b29093fd1c9c6ffcf3c9 commit 2449b9e5fe565be757a4b29093fd1c9c6ffcf3c9 Author: Mitchell Horne AuthorDate: 2022-07-18 21:23:16 +0000 Commit: Allan Jude 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 #include +#include + /* * 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 #endif +#include + 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 /* XXX acl_type_t */ #include /* accmode_t */ +#include /* 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 + * 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 +#include +#include + +#include + +#include +#include +#include + +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 /* XXX acl_type_t */ #include /* XXX accmode_t */ +#include /* 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 #include #include +#include #include #include #include @@ -72,6 +73,8 @@ #include #include +#include + #include #include @@ -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 #include +#include + #include #include @@ -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,